이번 포스팅의 경우 Naver D2 홈페이지에 작성된 좋은 내용이 있어 공부도 할겸 정리하고자 합니다.
원본 : https://d2.naver.com/helloworld/329631
Java의 GC는 크게 2 가지 작업을 수행합니다.
1. 힙(Heap) 내의 객체 중에서 가비지를 찾아낸다.
2. 찾아낸 가비지를 처리해서 힙의 메모리를 회수한다.
이 때, 가비지 대상을 판별하기 위해 GC는 reachability 개념을 사용합니다.
unreachable 객체의 경우 가비지로 간주해 GC를 수행하게 됩니다.
체이닝된 객체 참조관계에서 유효한 참조 여부를 파악하려면 항상 유효한 최초의 참조가 있어야 하는데 이를 객체 참조의 root set이라고 합니다.
아래 사진은 JVM에서 메모리 영역인 런타임 데이터 영역의 구조 입니다.
(런타임 데이터 영역, 출처 : https://d2.naver.com/helloworld/329631)
위 그림을 보면 힙에 존재하는 객체들에 대한 참조는 총 4가지 입니다.
위 네 가지 종류 중 힙 내의 다른 객체에 의한 참조를 제외한 나머지 3개가 ROOT SET으로 reachability를 판단하는 기준이 됩니다.
(Reachable 객체와 Unreachable 객체, 출처 : https://d2.naver.com/helloworld/329631)
먼저, Root set으로부터 시작한 참조사슬에 속한 객체들은 reachable 객체가 되며 참조사슬과 무관한 객체들이 unreachable 객체로 GC 대상이 됩니다.
위 사진 오른쪽 아래처럼 reachable 객체를 참조하더라도, 다른 reachable 객체가 이 객체를 참조하지 않으면 이 객체는 unreachable 객체가 됩니다.
위 그림에서 참조는 모두 java.lang.ref 패키지를 사용하지 않은 일반적인 참조이며 strong reference라고 부릅니다.