작성
·
242
·
수정됨
0
안녕하세요, 싱글톤 레지스트리 부분 강의를 들으며 궁금한 점이 있어 질문드립니다.
웹 어플리케이션에서 상태값을 가지지않는 객체를 매번 생성하는 것이 메모리의 부족을 일으켜 성능이 저하된다는 말에 동의합니다.
제가 궁금한 것은 이것이 크게 효과가 있는것인지에 대해 궁금합니다.
그렇게 생각하는 이유는 @Component 어노테이션이 달린 클래스들(비즈니스 로직이 담긴 스프링빈) 은 많은 상황에서 DTO 를 반환하게되는데 해당 DTO 를 인스턴스화해서 반환하는 작업이 계속 수행되면 결국에는 큰 차이가 없지않나[복잡도로 봤을때 객체의 인스턴스를 생성하는 횟수는 같은 O(n) 이 아닐까..?] 하는 생각이 들어 질문하게 되었습니다.
DB 커넥션을 맺는 DataSource 같은 빈이 아닌 어플리케이션의 비즈니스로직을 담은 빈을 싱글톤으로 다루는 것이 큰 효과가 있는지에 대해 답변을 부탁드립니다.
좋은강의 감사합니다.
답변 1
3
애플리케이션 서버는 하나의 서버에서 다수의 웹 요청을 다루게 됩니다. DTO는 각 요청마다 다른 응답을 만들어낼 때 사용되기 때문에 무조건 새로만들 수 밖에 없죠.
그에 반해서 변경되는 상태를 가지지 않는 서비스 오브젝트, 원래는 서블릿이 그랬고 지금의 스프링의 컨트롤러, 서비스, 리포지토리 같은 것들은 동시에 여러 요청을 처리하더라도 매번 새로 만들어야 할 이유는 없습니다. 그 안에서 파라미터로 전달되거나 메소드 내부에서 생성했다가 사용되고 사라지는 오브젝트들과는 다르죠. 그래서 서비스형 오브젝트는 싱글톤처럼 하나의 오브젝트를 만들어서 계속 사용하는 것이죠.
물론 그런 오브젝트도 매번 새로 만들 수도 있습니다. 그런데 단지 응답에 담을 정보를 넣기 위해서 단순하게 만들어 쓰고 끝나는 DTO와 달리, 기능을 담당하는 오브젝트들은 자신만 만들어지는 게 아니라, 자기가 사용할 다른 오브젝트가 또 필요하겠죠. 컨트롤러라면 최소한 하나 이상의 서비스 오브젝트가 필요하고, 하나의 서비스 오브젝트의 기능을 처리하려면 또 다른 서비스 오브젝트 또는 리포지토리, 기타 기능을 수행하는 많은 오브젝트가 필요합니다. 이걸 초당 수 백, 수 천 번씩 들어오는 웹 요청마다 새로 만들고 연결하고, 사용이 끝나면 가비지콜렉터에 의해서 정리하고 하는 건, 트래픽이 많지 않은 상황에서는 별 영향이 없어보이지만 조금만 사용자가 늘어나면 분명히 성능과 메모리 사용에 영향을 주는 불필요한 작업일 겁니다.
DataSource는 더더욱 싱글톤으로 사용해야 합니다. 하나의 DB 연결을 위해서는 JDBC 레벨에서 DB 연결정보를 가지고 커넥션을 생성하기 위해서, 드라이버 클래스를 확인하고, URL과 유저 정보 등을 이용해서 실제 DB 연결을 만들죠. 그게 워낙 자주 많이 사용되기 때문에 이걸 매번 하는 대신 대부분의 DataSource 구현은 한번 만든 걸 풀(pool)에 저장해두고, 매번 새로 만들지 않고 앞에서 만든 걸 재사용합니다. DB connection은 한번에 하나씩만 쓸 수 있기 때문에 싱글톤은 안 되고 여러개를 만들어서 돌려쓰죠. 바로 이런 connnection pool을 저장해두고 새로운 connect 요청이 올 때마다 사용 가능한 connection을 돌려주고 하는 복잡한 작업을 Datasource가 하고 있기 때문에라도 DataSource는 당연히 싱글톤으로 만들어서 사용해야 합니다.
DTO 는 단순하게 만들어 사용하고 제거되기 때문에 빠르게 가비지콜렉터에 의해서 정리되지만,
서비스 오브젝트, 컨트롤러, 리포지토리, 외부에 의존하는 빈 등은 여러 의존하는 객체가 존재하기에 가비지콜렉터에 의해 정리되기 더 어려워 싱글톤으로 사용하는것이 좋다라는 것으로 이해를 하였습니다.
답변 감사드립니다.