어쩌다프로그래머
6k
2011-02-09 11:23:51
15
9955

스프링 싱글톤 질문드립니다..


프레임웍을 접하다보니..
어떤것이 장점인지 모르고 책에 적힌대로만 쓰는경우가
발생하는군요...

스프링에 맞는 질문이 아닐수도 있지만..
스프링관점에서 질문좀 드릴게요..

스프링에서 빈 사용시..
디폴트는 싱글톤이죠...
하지만 설정을 추가해서..new 하는방식으로 사용중입니다,..

그러면 어떤경우가 싱글톤..
어떤경우가 new 가 적합한가요...

컨트롤러의 경우 만약 동시 접속자가 1000명이여서
동시에 한 컨트롤러를 동시에 호출한다고 가정할경우..

이상적인 퍼포먼스를 위해서라면
어떤 방식이 좋은걸가요...

명확하게 어떤경우에 이게 좋다라고 가정할수는 없겟지만..
싱클톤으로 할건지 아니면 new를 한건지
어드바이스적인 접근이 필요할것 같아 고수분들에게 여쭤봅니다..
0
  • 답변 15

  • greatbk
    46
    2011-02-09 11:54:03
    저도 고민하던 문제중 하나입니다..
    일단 제의견을 피력해 보겠습니다. 다른분들 의견도 접해보았으면 싶군요.. ^^

    기존의 WAS에서 서블릿을 실행할때도 싱글톤방식을 사용하지요. (스프링과 동일하게 하나의 인스턴스만 생성해서 사용하는것으로 알고 있습니다.)
    WAS에서만 싱글톤으로 사용하던것을 스프링 도입으로 인해 내부적으로 사용되는 컨트롤 객체들도 싱글톤으로 사용할 수 있게 됩니다.

    그러니깐.. WAS의 서블릿에서 MVC의 컨트롤러까지 싱글톤으로 확대적용하는 추세까지 온거라고 봐도 되겠지요.

    인스턴스를 새로 생성하는것과 싱글톤의 차이점이라 하면.. 단연 메모리 관리가 수월해지는것 아닐까요.
    사용자가 많아질수록.. 일일이 인스턴스를 new로 생성하다보면 런타임시에 서버의 힙메모리 사용량이 늘어나게 되죠.
    싱글톤을 사용했을때는 컨트롤러가 차지하는 메모리량은 아주 단촐하죠... 컨트롤러 클래스에 대한 인스턴스 하나만을 생성해서 메모리 적재하면 끝이니까요..

    단점은.. 컨트롤러 클래스에 상태변수등을 두어서는 안된다는것이겠지요. 필요한 데이터는 일일이 외부에서 DI해주어야 하고요..
    요약하자면 컨트롤러를 잘못 설계했을때.. 오류의 여지가 있다는점..
  • greatbk
    46
    2011-02-09 11:56:33
    참 그러고 보면... 오픈소스 프로그램중에서 소스를 까볼까 생각하는것들은 많은데.. 정작 실행은 못해보고 있다는것;;
    참 안타깝네요.
  • hjhbboy
    35
    2011-02-09 12:40:43
    컨트롤러와 동시처리는 의미가 맞지 않은것 같습니다.

    Spring MVC 에서 servlet 은 web.xml 에 기술 하셨드시,

    대게 DispatcherServlet 하나만 등록하여 사용 하실 겁니다.

    이 servlet이 클라이언트 요청시 마다 스레드로 처리 되는 겁니다.

    그때, ModelAndView 를 리턴 해줄수도 있고 아닐수도 있는 controller 가 호출 되는

    것이죠. 대부분 controller 는 상태가 없는 read only 객체 이므로 thread safe

    합니다.
  • greatbk
    46
    2011-02-09 13:07:39
    제가알기로는 WAS에서 모든 서블릿/JSP의 인스턴스를 하나씩만 생성해서 사용하는것으로 알고 있는데요...
    하나의 인스턴스를 모든 쓰레드에서 공유하는개념입니다. 그렇기때문에 서블릿/JSP에서 상태를 내부변수에 저장하면 문제가 되는것이죠..
    물론 소스까보고 드리는얘기는 아닙니다;;

    아시는분 있으면 제말이 맞는지 확인좀 부탁드립니다.
  • greatbk
    46
    2011-02-09 13:10:33
    아 그리고.. 메모리관리차원에서 싱글톤 사용시 GC의 부하를 줄일수 있는 이점도 있다고 보여지네요.
    VM이 하나의 프로세스단위이기 때문에 하나의 CPU(혹은 코어)밖에 활용할 수 없죠. 때문에 GC 쓰레드의 부하가 줄어들게 되면.. WAS의 가용성이 높아지게 되겠지요..
  • skynle
    382
    2011-02-09 13:10:35
    스프링에서 사용되는 싱글톤과..
    일반적으로 사용되는 싱글톤은 개념이 약간 트립니다.
    스프링에서 bean으로 등록하고 DI시킨 객체들은 결과가 new 한것과 같습니다.
    그러기 위한 프레임ㅤㅇㅝㅋ이 스프링이고요...

    스프링을 사용하면서 구지 new .. 로 객체를 생성해서 사용할 필요는 없는겁니다. 단, 데이터 저장을 위한 객체들(HashMap이나.. DTO(VO,Entity,...))은 예외입니다.
  • greatbk
    46
    2011-02-09 13:26:40
    메모리관리차원에서도 따져보니 장점이 여러개가 나오는군요..
    하나더 생각난건데.. 힙메모리에 객체생성 회수가 줄어들게 되면... OS차원에서 수행하는 메모리 조각모음 회수도 줄어들게 되겠지요.. 역시 시스템 자체의 가용성을 높이게 됩니다.
  • greatbk
    46
    2011-02-09 14:38:41
    http://www.geekinterview.com/talk/8855-instances-of-servlet.html

    위의 링크를 보시면... 서블릿도 하나의 인스턴스만 컨테이너에 의해 생성될 수 있다고 쓰여있네요 (답변쪽에 언급되어 있습니다.)
    제가 영어가 짧은관계로.. 뒷쪽은 해석이 확실히 안되긴 하네요.. ;;;
    해석이 잘못된거면 지적해주시면 감사하겠습니다.
  • greatbk
    46
    2011-02-09 14:48:50
    만일 제 의견이 맞다면... WAS에 스프링 프레임워크를 적용하였을 경우..
    서블릿 --> MVC컨테이너 --> MVC뷰어(JSP)
    모두 싱글톤 방식으로 각 클래스마다 하나의 인스턴스만 메모리에 적재 되겠네요..
    메모리효율면에서는 확실히 잇점이 있어보입니다.
  • jisqo
    268
    2011-02-09 15:08:54
    질문하신 이상적인 퍼포먼스 에대해서는 스프링기본 scope 인 싱글턴으로 하는게 맞다고 생각합니다. 많은 동접사용자가 사용하는 시스템에서 불필요한 new 인스턴스 생성은 사용자 쓰레드가 증가할수록 메모리 도 비례증가하므로 was 의 full gc 작업발생 확율도 높아지죠. 스프링에서 인스턴스 생성은 윗분들 말씀하신대로 stateful 즉, 상태를 가지는 bean들 예를들면 DTO(VO) 같은 was와 user가 1:1 관계로 정보상태를 유지해야할 객체들만 인스턴스생성 하는것이 맞다고 생각합니다.
  • 어쩌다프로그래머
    6k
    2011-02-09 15:36:25
    서블릿은 싱글톤이 맞구요...
    음 제 질문은 퍼포먼스나 작동 방식이었는대..ㅠㅠ

    왜냐면 하나의 싱글톤을 동시에 1000 엑세스사 이루어질경우
    그 싱글콘 객체는 해당업무를 실행해야 하는대..

    이부분에서 퍼포먼스적인 이슈가 궁금해서였습니다..
  • greatbk
    46
    2011-02-09 16:17:06
    퍼포먼스측면에서도 싱글톤이 낫습니다. 당연한거지요.
    만일 동접1000명이라 해도... 각각의 쓰레드가 빈인스턴스에 접근할때는 임계영역에 진입하지 않고.. 곧바로 빈인스턴스를 읽어서 사용합니다.
    싱글톤이라 해도 성능상 손해보는것이 없어요..
  • skynle
    382
    2011-02-09 18:45:57
    최초 어플이 디플로이될때 스프링에서는 모든 bean을 힙에 넣어둡니다.
    그리고.. 어플에서 사용할때 이 메모리에 넣어둔놈을 clone()으로 복제해서 던져줍니다. 하나의 객체가 모든 세션을 관리하는 일반적인 싱글톤과는 개념이 좀 다릅니다. 첫번째 접속한 유져와 두번째 접속한 유져는 결과적으로 독립적인 객체를 사용하는거지요..
  • greatbk
    46
    2011-02-09 22:49:02
    /skynle
    저도 확실히 모르던부분을 알려주셨네요. 감사합니다.
    나름 테스트해보긴했는데.. 항상 빈이 복제되는것은 아닌것 같습니다.
    예를들자면 쓰레드별 하나씩 이라던가... 하는 별도의 규칙이 있는듯해요.

    아래는 스프링 빈을 얻어서 레퍼런스값을 찍어본 결과입니다..

    springTest: test.springTest@1440578d
    springTest: test.springTest@1440578d
    springTest: test.springTest@1440578d

    호출 한번당 한줄씩 찍는건데.. 같은 객체를 참조하네요
    clone()으로 얕은복사가 된다면.. 다른객체주소가 찍히는게 정상인데 쫌 이상하죠.
  • 어쩌다프로그래머
    6k
    2011-02-10 00:07:48
    /skynle
    모든 빈을 힙에 넣어두고 가져다 쓰는것은 맞습니다..
    하지만 님말대로 클론을 한다는것은 싱글톤이 아니지요..
    결국 방식의 차이지 new랑 같은 개념이겟죠...
    하지만 스프링의 기본은 싱글톤입니다..
    결국 클론이 아닌..객체를 바로 접근 하는것이겟죠...

    만약 아니라면 지금껏 제가 잘못알고 스프링을 사용한것이 되는군요..ㅠㅠ
  • 로그인을 하시면 답변을 등록할 수 있습니다.