Garbage Collection이란 사용하지 않는 객체를 메모리에서 삭제해주는 작업을 의미한다.
C/C++의 경우 개발자가 객체 해제를 직접 실행해야하지만 자바의 경우 JVM에서 GC를 수행한다. 객체의 메모리를 해제해주지 않으면 메모리 누수(Memory Leak)이 발생 할 수 있다.
신규로 생성한 객체의 대부분은 금방 사용하지 않는 상태가 되고, 오래된 객체에서 신규 객체로의 참조는 매우 적게 존재한다는 가설.
이 가설에 기반하여 자바는 Young 영역과 Old 영역으로 메모리를 분할하고, 신규로 생성되는 객체는 Young 영역에 보관하고, 오랫동안 살아남은 객체는 Old 영역에 보관한다.
Stop The World는 가비지 컬렉션을 실행하기 위해 JVM이 애플리케이션의 실행을 멈추는 작업이다.
GC가 실행될 때는 GC를 실행하는 쓰레드를 제외한 모든 쓰레드들의 작업이 중단되고, GC가 완료되면 작업이 재개됩니다.
당연히 모든 쓰레드들의 작업이 중단되면 애플리케이션이 멈추기 때문에,GC의 성능 개선을 위해 튜닝을 한다고 하면 보통 stop-the-world의 시간을 줄이는 작업을 한다.
MARK
Stop The World를 통해 모든 작업을 중단시키면, GC는 스택의 모든 변수 또는 Reachable 객체를 스캔하면서 각각이 어떤 객체를 참고하고 있는지를 탐색하고 사용되고 있는 메모리를 식별한다.
Sweep
이후에 Mark가 되지 않은 객체들을 메모리에서 제거한다.
적은 메모리, 적은코어에 적합한 방식으로 Serial GC의 Young 영역은 알고리즘(Mark Sweep)대로 수행한다. 하지만 Old 영역에서는 Mark Sweep Compact 알고리즘이 사용되는데, 기존의 Mark Sweep에 Compact라는 작업이 추가된다.
Compact는 Heap 영역을 정리하기 위한 단계로 유요한 객체들이 연속되게 쌓이도록 힙의 가장 앞 부분부터 채워서 객체가 존재하는 부분과 객체가 존재하지 않는 부분으로 나누는 것입니다.
Serial GC와 기본적인 알고리즘은 같으나, Parallel GC는 멀티 쓰레드를 사용한다. 이로 인해 stop-the-world하는 시간이 줄어 애플리이케이션 성능이 개선됐다. 따라서 Parallel GC는 메모리 크기가 클 때와 다중 코어에서 유리하다.
Parallel GC는 Old 영역의 GC 알고리즘이 Mark-Summary-Compaction을 거친다. Summary 단계는 Sweep과 달리 GC를 수행한 영역에 대한 객체 식별을 거친다.
Young Generation과 Old 영역이 존재하나, 고정된 크기와 위치로 존재하지 않는다.
G1 GC는 CMS GC를 대체하기 위해서 만들어진 GC로 Heap Space를 Region이라는 일정 크기로 나누어 각 Region에 Young, Old를 동적으로 부여한다.
Stop-the-world 이후 Initial marking 시 살아있는 객체만 찾는다.
이후 concurrent mark 단계에서 참조를 따라가며 새로 추가되거나 참조가 끊긴 객체들을 remark 한다.
모든 작업이 멀티스레드 환경에서 동시진행되기 때문에 stop-the-world 시간이 매우 짧은 대신 memory와 CPU 를 많이 사용하고 compaction 단계가 제공되지 않는다.