Java 객체 생존 판별 및 가비지 컬렉션 원리

객체 생존 여부 판단 기준

참조 카운터 방식의 한계

참조 카운터는 객체마다 카운터를 할당하여 참조 발생 시 증가, 참조 해제 시 감소시키는 방법입니다. 카운터가 0이면 가비지 컬렉션 대상으로 간주되지만, 순환 참조 상황에서는 실제로 사용되지 않음을 실험으로 확인할 수 있습니다.

public class GCValidation {
    private static final int SIZE_1MB = 1024 * 1024;
    private byte[] data = new byte[10 * SIZE_1MB];

    void validate() {
        Node nodeX = new Node();
        Node nodeY = new Node();
        nodeX.ref = nodeY;
        nodeY.ref = nodeX;
        
        nodeX = null;
        nodeY = null;
        System.gc();
    }
    
    public static void main(String[] args) {
        new GCValidation().validate();
    }
}

class Node {
    Node ref;
}

실행 결과 GC 로그에서 메모리 회수(496K→0K)가 발생하므로, 상호 참조 객체도 정상적으로 회수됨을 확인할 수 있습니다. 이는 JVM이 참조 카운터 방식만으로 객체 생존을 판단하지 않음을 증명합니다.

도달 가능성 분석 알고리즘

GC Roots로부터 시작해 참조 체인을 탐색하는 방식입니다. 객체가 GC Roots와 직접적/간접적으로 연결되지 않으면 회수 대상으로 판단합니다. 상호 참조되어 있더라도 루트에서 도달 불가능하면 가비지 컬렉션 대상이 됩니다.

세대별 가비지 컬렉션 기법

신규 객체 할당 영역

  • Eden: 새로 생성된 객체 배치
  • Survivor: GC 생존 객체 임시 보관 (From/To 영역)

객체는 초기에 Eden 영역에 할당됩니다. Eden이 가득 차면 Minor GC가 트리거되며, 복사 알고리즘을 통해 생존 객체는 Survivor 영역으로 이동합니다. 이때 매 GC마다 객체의 생존 연령이 증가하며, 기본 임계값(15, -XX:MaxTenuringThreshold 조절 가능)에 도달하면 Old 영역으로 승격됩니다.

메모리 구성 옵션:

-Xms: 힙 초기 크기
-Xmx: 힙 최대 크기
-Xmn: 신규 영역 크기
-XX:SurvivorRatio: Eden/Survivor 비율
-XX:NewRatio: 신규/구형 영역 비율

구형 객체 관리 영역

Old 영역이 가득 차면 Major GC가 실행됩니다. 이때 표시-정리(Mark-Sweep) 또는 표시-압축(Mark-Compact) 알고리즘이 사용되며, Minor GC 시 승격될 객체 크기가 Old 영역 잔여 공간을 초과할 경우 Full GC가 발생합니다.

태그: java 가비지컬렉션 힙메모리 GC알고리즘 JVM튜닝

7월 30일 00:47에 게시됨