자바에서 가비지 컬렉터(GC)의 GC Roots는 힙 메모리에서 객체를 도달 가능한 상태로 유지하는 시작 지점이다.
GC는 메모리에서 더 이상 사용되지 않는 객체를 식별하고(Mark) 회수하는 작업(Sweep)을 수행하는데, 이때 어떤 객체가 사용 중인지 판단하기 위해 GC Roots에서 시작하여 도달할 수 있는 객체를 활성
객체로 간주한다.
GC Roots로 간주되는 객체들
어떤 게 Roots다! 라고 딱 정해진 건 없지만 일반적으로 다음과 같은 객체들이 GC Roots로 간주된다.
1. 클래스(Class)
JVM의 시스템 클래스 로더에 의해 로드된 클래스는 메서드 영역(Method Area)에 저장되며, 클래스의 정적 필드와 메서드는 프로그램 전반에서 전역적으로 접근 가능하다.
이러한 정적 필드가 참조하는 객체는 클래스 로더가 관리하며 프로그램 종료 전까지 참조를 유지하므로 GC Roots로 간주된다.
2. 스택 로컬(Stack Local)
JVM의 스택에 저장된 메서드 매개변수와 지역 변수는 메서드 실행 동안 유효하며, 이 변수들이 참조하는 객체는 GC Roots로 간주된다.
스레드의 호출 스택에서 활성화된 스택 프레임의 변수들은 메모리 해제 대상이 아니기 때문이다.
3. 활성화된 자바 스레드(Active Java Threads)
현재 실행 중이거나 대기 상태인 자바 스레드 객체는 GC에 의해 수집되지 않는다. 스레드가 종료되지 않는 한, 스레드와 관련된 모든 객체는 GC Roots로 간주된다.
4. JNI 참조(JNI References)
네이티브 코드(Java Native Interface)에서 참조되는 객체는 JVM 외부에서 관리되며 GC에서 수집되지 않는다. 네이티브 메서드가 자바 객체를 참조할 때 이 객체는 GC Roots로 간주된다.
5. 모니터(도달 가능한 잠금)
synchronized
블록이나 메서드에서 사용되는 모니터 객체는 동기화 잠금을 유지하는 동안 GC 대상에서 제외된다. 이는 동기화된 코드의 안전성을 보장하기 위해 객체를 유지하는 JVM의 메커니즘이다.
6. JVM 내부의 특별 객체
JVM 구현에 따라 특별히 관리되는 객체가 GC 대상에서 제외될 수 있다.
예외 처리 클래스, 시스템 클래스 로더 또는 커스텀 클래스 로더 등 중요한 객체가 포함될 수 있다.
이는 내부적으로 JVM의 동작에 필수적인 객체로 간주되어 GC Roots로 처리된다.
각 JVM에 따라 어떤 객체가 GC 루트인지에 대한 구체적인 문서화는 없지만, 일부 인기 있는 Java IDE는 GC 루트를 기준으로 메모리를 분석하는 기능을 제공한다. 이는 애플리케이션의 메모리 누수를 분석할 때 유용하다.
'💻 Dev > Java' 카테고리의 다른 글
리플렉션(Reflection)으로 DI 구현해보기 +단점 (0) | 2024.12.22 |
---|---|
Stack은 왜 상속의 실패 사례일까? (0) | 2024.12.12 |
System.out.println을 실무에서 사용하면 안되는 이유 (1) | 2024.12.05 |
Out-of-Memory(OOM)는 왜 발생하고, 어떻게 예방할까? (0) | 2024.11.30 |
instanceof 사용을 지양해야하는 3가지 이유 (0) | 2024.11.29 |
JVM Warm-up, feat. 스프링 첫 요청이 오래 걸리는 이유 (0) | 2024.11.28 |