이번에 설명하는 건 다음 장을 위한 기초지식 쌓는 것. 지루하거나 이해 어렵다면 건너뛰었다가 실무에서 어려움 직면시 봐도 ㄱㅊ음
3.4.1 루트 노트 열거
흠 다음기회에 할까…아니다 이러면 안보니까 하는김에 해야됨
- 효율적인 가상 머신 구현하기의 첫 예로 루트 노드 열거(root node enumeration) 알아보자
- 루트 노드 열거란
- 도달 가능성 분석 알고리즘에서 GC 루트 집합으로 부터 참조 체인 찾는 작업
- GC 루트로 고정할 수 있는 노드는 주로 전역참조(상수, 클래스 정적 속성 등)와 실행 콘텍스트(실핼 프레임의 지역 변수 테이블 등)에 존재함
- 목표는 명백 하지만 참조 체인 스캔 과정을 효율적으로 구현하기 만만치 않음
- 루트 노드 열거란
- 오늘날 자바 애플리케이션은 점점 거대해지고있음
- 메서드 영역만 수백GB 사례도 있음
- 그 안에 있는 클래스와 상수의 수는 엄청날 것!
- 하나하나 모든 참조 확인하려면 엄청난 시간 걸릴것은 뻔함
- 지금까지 모든 컬렉터는 루트 노드 열거 단계에서 사용자 스레드를 일시 정지 해야 했음
- 루트 노드를 열거하려면 스탑 더 월드를 못 피한다는 이야기!
- 앞서 파편화된 메모리 조각들 모을때처럼
- 현재 도달 가능성 분석 알고리즘의 참조 체인 찾기 과정에서 가정 오래걸리는 작업은 다행히도 사용자 스레드와 동시 실행 가능(3.4.6 동시 접근 가능성 분석 참고)
- 하지만 루트 노드 열거 만큼은 반드시 일관성이 보장되는 스냅숏 상태애서 수행해야됨
- 여기서 ‘일관성’이란 열거 작업이 진행되는 동안 실행 서브시스템이 ‘특정 시점으로 고정’된 것 처럼 보인다는 뜻
- 더 구체적으로 말하자면, 루트 노드들의 참조 관계가 변치 않아야 된다는 것!
- 이 조건 못 지키면 분석 결과 신뢰 불가
- 이것이! 가컬 시 모든 사용자 스레드가 일시 정지 해야 하는 이유.
- 심지어, 일시 정지 기간을 제어할 수 있거나 (거의) 정지 않는 CMS, G1, ZGC 같은 컬렉터들도 루트 노드를 열거할 때만은 일시 정지 피할 수 없다
- 현재 주쥬 자바 가상 머신들은 ‘정확한 가비지 컬렉션’ 사용한다.
- 따라서, 사용자 스레드가 정지한 후 실행 콘텍스트와 전역 참조의 위치를 빠짐없이 확인할 필요 없음
- 그 대신 가상 머신이 객체 참조가 저장된 위치를 직접 알아낼 방법이 있어야함
- 핫 스팟은
OopMap이란 데이터 구조 이용하여 이를 해결- 먼저 클래스 로딩이 완료되면 객체에 포함된 각 데이터 타입 확인
- 그리고 JIT Compile 과정(11장 참고)에서 스택의 어느 위치와 어느 레지스터의 데이터가 참조인기 기록
- 이런식으로 컬렉터는 메서드 영여과 다른 GC 루트들로 부터 시작하여 추적해 보지 않고도 스캔 과정에서 이를 직접 얻어냄
- 코드 3-3은 핫스팟 클라이언트 가상 머신이 생성한 String::hashCode() 메서드의 네이티브 코드 중 일부