싱글톤은 항상 stateless하게!
Created Time: September 25, 2022 12:27 AM
Last Edited Time: December 23, 2022 5:39 PM
References: https://esoongan.tistory.com/177
https://brownbears.tistory.com/519
Status: In progress
의문점
싱글톤인데 전역변수를 stateful하게 활용해도 문제없는가?? → 문제있다.
설명
Spring은 스프링 빈에 관리하는 클래스는 하나의 객체를 처음에 생성하고, 그후에는 모든 요청에 모두 같은 객체를 사용한다.(=싱글톤) → 따라서 state를 가지면 안된다.
싱글톤 구조 자체가 스택은 thread-safe(지역 변수와 매개변수 등등) 함수,쓰레드 완료시, 사라짐
공유되는 영역(힙,코드, 데이터)은 쓰레드간의 공유가 되기 때문에, 전역변수로 활용시, 힙에 저장되는 것은 문제가될수있다. → 공유됨으로 싱글톤 힙에 할당되는것은 항상 stateless해야한다.
스레드는 왜 Controller의 메소드를 어떻게 공유하는데??
- Controller 객체를 생성하면 객체는 힙에 생성되지만 해당 클래스의 정보(메소드라면 메소드 처리 로직(명령들))는 메소드영역에 생성된다
- 결론적으로 싱글톤으로 관리되는 빈의 경우 상태 정보를 갖지 않기 때문에 요청의 수와 상관없이 싱글턴 객체의 장점을 이용할 수 있었던 것이다.
- 만약 빈이 상태정보를 갖게된다면 스레드들간의 동기화가 필요하고 오버헤드가 발생, 객체를 하나만 만들고 컨테이너에서 단순히 꺼내쓸수 있었던 장점을 잃게 된다.
JVM 메모리 구조
JVM은 운영체제에서 할당 받은 메모리 영역을 아래와 같이 구분해서 사용합니다.
기본형과 참조형 타입 차이
- 기본타입은 스택에 값저장
- 참조 타입은 주소값을 스택영역에 갖고, 실제 값은 힙 영역에 저장
메소드 영역
메소드 영역은 JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역입니다. 메소드 영역에서는 코드에서 사용되는 class들을 클래스 로더로 읽어 클래스 별로 static field와 constant, method code, constructor code 등을 분류해서 저장합니다.
힙 영역
힙 영역은 객체와 배열이 생성되는 영역입니다. 여기에 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조합니다. 만일 참조하는 변수나 필드가 없다면 의미없는 객체가 되기 때문에 JVM에서는 garbage collector로 처리를 합니다.
JVM 스택 영역
JVM 스택은 메소드를 호출할 때마다 frame을 추가하고 메소드가 종료되면 해당 프레임을 제거하는 동작을 수행합니다.
프레임 내부에는 로컬 변수 스택이 있는데 기본 타입 변수와 참조 타입 변수가 추가되거나 제거됩니다. 스택 영역에 변수가 생성되는 시점은 최초로 변수에 값이 저장될 때입니다. 변수는 선언된 블록 안에서만 스택에 존재하고 블록을 벗어나면 스택에서 제거됩니다.