Java Garbage Collector
GC
Java는 C / C++ 과는 달리 개발자가 메모리의 할당, 해제를 관리하지 않는다.
따라서 생성된 객체는 Java Garbage Collector에 의해 이루어지며, JGC는 JVM내부에 존재.
객체메모리 해제 시, Java 객체를 null처리할 수도 있고, System.gc()를 호출할 수도 있지만, System.gc()는 시스템 성능에 영향을 미칠 수 있으므로 호출을 자재하여야 한다.
Java Garbage Collector의 두 가지 전재 - weak generational hypothesis
대부분의 객체는 금방 접근 불가능(unreachable) 상태가 된다.
Old객체에서 Young객체의 참조는 적게 이루어진다.
객체의 메모리 할당과 프로모션(Allocation and Promotion)
처음 객체가 생성[Allocated to somewhere in memory] 되면 JVM의 Young영역에 할당
- Minor GC
Unreachable 상태가 되지 않아, 살아남은 객체들은 Old 영역으로 Promotion
- Major GC[Full GC]
- Old에서 Young으로 객체 참조가 이루어질 경우 Card Table 에 표시가 되며, Minor GC 대상의 식별은 Card Table을 보고 식
Old 영역에서도 살아남은 객체들은 Permanent 영역으로 이동
Young영역
Eden (1개) + Survivor(2개)
대부분의 객체는 처음 Eden영역에 할당.
GC이후 Eden에서 살아남은 객체는 Survivor영역 중 하나로 이동하며, Eden영역에서 GC가 발생하면, 살아남은 객체가 존재하는 Survivor영역으로 객체 이동.
하나의 Survivor영역이 가득차게 되면, 살아남은 객체들은 모두 다른 Survivor영역으로 이동. 이 과정을 반복 하며 계속 살아남는 객체들은 Old로 이동.
Survivor 중 한 영역은 반드시 빈 상태여야 하며, 두 영역 모두 사용중이거나 사용량이 0이면 비정상 상태
Old 영역
Young영역에서 살아남은 객체들[Eden -> Survivor] 이 존재하는 공간.
Old 영역이 가득 차게 되면, JVM은 GC를 실행
GC의 종류 - Serial GC, Parallel GC, Parallel Old GC, Concurrent Mark & Sweep GC (CMS) , G1 GC [ Garbage First ]
- Serial GC
- 운영환경에서 사용해서는 안되는 GC
- mark - sweep - compaction 라는 알고리즘 사용
- mark [ Old 영역에 살아남은 객체 식별 ] -> sweep [heap 앞부분 부터 확인하여, 살아남은 객체남 남기고 제거] -> compaction [각 객체들을 Heap 앞부분 부터 연속적으로 쌓는다.]
- 적은 CPU와 메모리 를 갖는 상황에서 사용
- 적용옵션 : -XX:+UseSerialGC
- Parallel GC
- GC를 하는 알고리즘은 기본적으로 Serial GC와 같지만, 멀티쓰레드를 사용하여 동시적으로 진행
- 적용옵션 : -XX:+UseParallelGC
- Parallel Old GC
- mark - summary - compaction 알고리즘을 사용하며, summary의 경우, sweep 과 달리 앞서 GC가 진행된 영역에서 별도로 살아남은 객체를 식별한다는 점에서 차이남.
- 적용옵션 : -XX:+UseParallelOldGC
CMS GC
초기 marking 단계에서 클래스로더와 가까운 객체만 찾는 것으로 끝[STW].
Cuncurrent 단계에서 mark 단계에서 살아있다고 확인된 객체를 쫓아가면서 참조객체 확인[쓰레드]
Remark 단계에서 Cuncurrent 단계에서 끊기거나 추가된 객체 확인[STW].
Concurrnet Sweep에서 쓰레드를 통해 쓰레기 정리
compaction이 별도로 제공되지 않아, 추후에 조각이 많아지면, compaction 시 STW시간이 길어짐.
- Serial GC
REF