Java
[JVM 밑바닥까지 파헤치기] 3-3. 가비지 컬렉터와 메모리 할당 전략: 구현
noahkim_
2024. 12. 21. 20:00
저우즈밍 님의 "JVM 밑바닥까지 파헤치기" 책을 정리한 포스팅 입니다
1. 루트 노드 열거
- GC를 수행하려면 어떤 객체가 살아있는지 먼저 알아야 함
- 이를 위해 GC Root라는 출발점을 기준으로 참조 그래프를 따라 탐색함
- 대표적인 GC Root는 스레드 스택, 정적 변수, 레지스터가 있음
항목 | 설명 |
Stop-the-world |
- 루트 노드 탐색은 실행 중인 애플리케이션과 충돌하므로 반드시 stop-the-world가 필요함
|
OopMap (Object Offset Map) |
- 각 스레드 스택에 존재하는 객체 참조의 위치 정보를 담은 맵
- 모든 시점이 아닌, Safe Point에서만 생성되어 성능 최적화됨 |
객체 이동 지원 |
- GC 과정에서 객체 주소가 바뀌는 경우, OopMap을 통해 스레드 스택 내 참조도 정확하게 갱신함
- 이는 객체 이동을 안전하게 보장하는 핵심 기술임 |
2. 안전
Safepoint
- 객체 참조가 변경하지 않을 것임을 보장하는 지점
- GC 발생 시 모든 스레드가 가장 가까운 safepoint까지 실행하고 멈춤
- Safepoint에서만 GC, 메서드 호출, 스레드 상태 점검 등이 가능함
구분 | 설명 | 특징 |
자발적 멈춤 | 각 스레드가 플래그 비트를 확인하고 가까운 안전 지점에서 스스로 멈춤 |
GC가 스레드 수행에 관여하지 않음
→ 효율적이며 자주 사용됨 |
선제적 멈춤 | JVM이 인터럽트를 발생시켜 스레드를 강제로 안전 지점까지만 실행시키는 방식 |
sleep, block 상태 스레드는 응답 못함
→ 거의 사용되지 않음 |
Safe Region
- GC의 영향에서 제외되는 스레드 영역
- GC가 실행되는 동안 스레드가 참조 관계를 변경하지 않도록 보장됨
- 안전 지역에 있다면 안전 지점까지 도달하지 않아도 GC가 제대로 동작할 수 있음
- 사용자 스레드는 safe region에 진입했음을 표시함
3. 기억 집합
- 비회수 영역에 있는 객체들이 회수될 참조들을 기록하는 데이터 구조
- 젊은 세대와 노년 세대간의 참조 관계를 추적하는 데 사용됨
정밀도
구분 | 설명 | 장점 | 단점 |
워드 정밀도 | 메모리 워드(기본 단위)마다 참조 기록 | 관리 단위 작음, 정확성 높음 | 공간 사용 많음 |
객체 정밀도 | 객체 단위로 참조 기록 | 공간 효율적 |
객체 내부 참조 위치 파악 어려움
|
카드 정밀도 | 메모리 블록(카드 단위)마다 참조 기록 | 공간 효율적 |
객체 내부 참조 위치 파악 어려움
|
카드 기반 관리
- 카드 정밀도로 참조 시 사용하는 방식
항목 | 설명 |
카드 테이블 |
카드 정밀도로 참조를 추적하는 바이트 배열 구조
|
- 카드 페이지 |
메모리 블록 하나의 사이즈
하나의 카드 페이지는 특정 메모리 영역을 지칭 |
- 변경 시점 |
참조 타입 필드에 값이 대입될 때 카드 페이지가 더럽혀짐(dirty 처리됨)
|
4. 쓰기 장벽
- 카드 페이지 관리 방식
항목 | 설명 |
AOP Aspect |
- 참조 타입에 객체가 대입되면 어드바이스 실행
- 보통 대입 후 추가 동작 수행 (After Advice) |
단점 |
- 오버헤드 발생: 매번 기록 및 검사
- 거짓 공유: 실제 공유 안 해도 같은 캐시라인이면 동기화됨 |
거짓 공유 |
- CPU 캐시는 캐시라인 단위로 관리
- 변수들이 같은 캐시라인에 있으면 불필요한 동기화 발생 - 라이트백, 무효화 등 추가 작업 유발 → 성능 저하 |
관련 매개변수 | -XX:+UseCondCardMark: 거짓 공유에 의한 불필요한 카드마크를 줄이기 위한 설정 |
5. 동시 접근 가능성 분석
삼색 표시 기법
- 객체 그래프 탐색 중, 객체를 세가지 색으로 구분하여 어떤 상태인지 추적하는 알고리즘
- 마주치는 객체들에 특정 조건의 방문 객체임을 체크
색상 | 설명 | 의미 및 상태 |
흰색 | - 가비지 컬렉터가 아직 방문하지 않은 객체 - 최종적으로도 흰색이면 가비지로 판단되어 회수됨 |
❌ 생존 불확실 → 수거 대상
|
회색 | - 가비지 컬렉터가 방문은 했지만, 내부 참조 전부 스캔되지 않은 상태 |
⏳ 생존 여부 판단 진행 중
|
검은색 | - 가비지 컬렉터가 방문했고 내부 참조까지 모두 스캔 완료된 상태 |
✅ 확실한 생존 객체→ 재방문 불필요
|
객체 사라짐 문제
- 사용자 스레드와 GC가 동시 수행 시, 문제 발생
- GC가 아직 검사를 완료하지 않았는데 사용자 스레드가 참조를 끊는 경우, 회수되지 않아야 할 객체가 회수됨