기본 설명
Heap과 Stack은 둘 다 JVM의 메모리 영역중 하나입니다.
Stack
- 메소드 호출과 지역 변수를 저장하는 영역입니다.
- 각 스레드마다 별도의 스택이 존재하고, 메소드 호출 시마다 스택프레임 생성 후, 메소드의 지역 변수와 매개변수가 저장됩니다. 그리고, 메소드 종료시 스택 프레임에서 스택이 제거됩니다.
- 기본적으로 정적 크기를 갖고 있습니다. 많은 재귀 호출이나 메소드 호출이 많으면 StackOverflow가 발생합니다.
Heap
- 힙은 동적으로 할당된 객체들을 저장하는 영역입니다.
- 일반적으로
new
예약어로 객체를 Heap에 동적 할당하게 됩니다. (객체에 대한 참조는 스택에 저장)
- 객체에 대한 참조가 없어지면, *가비지 컬렉터 가 힙에서 회수하여 메모리를 재 사용하게 됩니다.
- 힙은 모든 스레드에서 공유하는 영역 입니다.
- 힙은 JVM 시작 시에 초기 크기로 시작하고, 동적으로 확장될 수 있습니다.
- 초기 힙 사이즈를
-Xms
로 늘리고 줄일수 있습니다.
- 최대 힙 사이즈를
-Xmx
로 늘리고 줄일수 있습니다.
- Heap 메모리도 OutOfMemoryError가 발생할 수 있습니다. → JVM이 더 이상 메모리를 할당할 수 없을때 발생하는 예외입니다.
*가비지 컬렉터란?
- 주로 힙 내의 객체들을 대상으로 합니다. 사용하지 않는 객체를 식별하고, 참조 되지 않는 객체를 자동으로 메모리에서 해제합니다.
- Oracle 문서 에서는 “Reachability”라는 개념을 사용합니다. reachable인가 unreachable을 분별해서, unreachable하면 GC대상입니다.
- rootset으로 부터 시작한 참조 객체들은 reachable이고 무관한 객체는 unreachable입니다.
"가비지 컬렉터(Garbage Collector)"와 "GC(Garbage Collection)"는 메모리 관리를 위해 자동으로 실행되는 프로세스를 의미하는 용어로 사용되며, 사실상 동일한 개념을 나타냅니다.
*가비지 컬렉터가 그러면 어떻게 Reachable한 객체인지 판별 할 수 있을까?
- 가비지컬렉터는 root라고 알려진 객체 집합(root set)을 식별합니다.
- Root Set은 각 스레드별 스택프레임, 정적 변수(Static 변수), Java Native Interface (소위, JNI) 에 의해 생성된 객체에 대한 참조, 클래스로더가 로드한 클래스(GC root)등이 해당됩니다.