JVM의 힙영역에서 사용하지 않는 객체를 삭제하는 프로세스를 말한다.
어떤 객체에 유효한 참조가 존재한다면 Reachable, 그렇지 않다면 Unreachable이라고 한다. GC Root에서부터 차근차근 참조를 따라가서 특정시점에 참조되는 객체가 있고 참조관계가 끊긴 객체가 있게 된다.
GC Roots가 될 수 있는 대상은 stack영역에 있는 데이터나 파라미터, method 영역의 static데이터들, JNI(java native interface)에 의해 생성된 객체들, 힙영역의 다른 객체에 의한 참조가 해당된다. 여기서 Unreachable 객체가 GC의 수거대상이 된다.
객체가 null인 경우, 블럭 실행 후 블럭 안에 생성된 객체, 부모 객체가 null인 경우 포함된 자식객체가 해당된다.
💡GC가 동작할 때마다Marking-Sweep-Compacting 하는 과정이 반복된다.
GC는 GC Root로부터 모든 변수를 스캔하면서 각각 어떤 객체를 참조하고 있는지 찾아서 마킹한다. 즉 Reachable한 객체와 UnReachable한 객체를 식별하는 과정이다.
Unreachable한 객체들을 힙에서 제거하는 과정이다. 참조되지 않은 객체를 제거하고 메모리를 반환한다. 메모리 Allocator는 반환되어 비어진 블럭 참조위치를 저장해두었다가 새로운 오브젝트가 선언되면 할당되도록 한다.
퍼포먼스 향상을 위해서 Sweep 후 분산된 객체들을 힙의 시작주소로 모아서 메모리 할당부분과 그렇지 않은 부분으로 나눈다.
Yong genereation은 새로운 객체들이 할당되는 영역을, Old Generation영역은 Yong Generation영역에서 오래 살아남은 객체들이 존재하는 영역을 말하며 Meta Space(Permanent영역)는 가비지 컬렉션 시 필요한 클래스와 메서드 요약정보가 존재하는 영역이다.
새로운 객체가 Eden영역에 할당되고 모든 Eden에 할당되면 더이상 할당된 곳이 없으므로 Minor GC가 발생하고 Marking이 발생한다. 여기서 살아남은 객체들은 survivor영역으로 이동한다. 규칙은 survivor0에 객체가 들어있으면 survivor1에는 무조건 비워줘야하고 survivor1에 객체가 들어있으면 survivor0은 비워줘야 한다.
이후 SWeep으로 unreachable한 객체들이 삭제된다. 살아남은 객체들은 Age가 증가한다.(Aging) 다시 Eden 영역에 새로운 객체들로 할당되고 자리가 없으면 Minor GC가 발생한다.
앞서 survivor0에 저장이 되었었다면 이번에는 survivor1영역으로 살아남은 객체들이 이동된다. 그리고 Sweep으로 unreachable한 객체 삭제-살아남은 객체의 age 증가가 일어난다.
📍이렇게 Minor GC가 발생할때마다 Eden영역에서 Survivor영역로 이동하게 된다.
이 과정이 계속 반복된다.
객체의 age가 특정 age 임계값에 도달하면 Old Generation 영역으로 이동한다. (promoted) age값이 높은 객체들로 모두 old generation 영역이 할당되면 Major GC가 발생하게 된다.
여기서 파란색 영역은 객체를 참조하고 있는 영역이라고 보면 된다. Minor collections = minor gc, major collections = major gc
Weak Generational Hypothesis 가설은 신규로 생성된 객체는 금방 사용하지 않는 상태가 되고 오래된 객체는 신규객체로의 참조가 매우 적제 존재한다는 가설이다.
이 가설에 기반해서 자바는 young 영역과 old 영역으로 메모리를 분산하고 신규로 생성되는 객체는 young 영역에 보관하고 오랫동안 살아남은 객체는 old영역에 보관한다.
GC를 실행하기 위해 JVM이 애플리케이션 실행을 멈추는 것을 말한다. GC를 실행하는 스레드 이외 모든 스레드가 작업을 중단한다.