저우즈밍 님의 "JVM 밑바닥까지 파헤치기" 책을 정리한 포스팅 입니다

1. 런타임 데이터 영역
| 영역 이름 | 설명 | 
 주요 특징 및 구성 요소 
 | 
| 메서드 영역 | 클래스 수준 메타데이터 저장 | 
 - 클래스 버전, 필드, 메서드, 런타임 상수 풀 포함 
 | 
| └ 런타임 상수 풀 | 컴파일 시 생성된 상수 및 심볼 정보 저장 | 
 - String.intern() 등이 사용됨 
 | 
| 힙 (Heap) | 객체 인스턴스가 저장되는 가장 큰 영역 | 
 - GC 관리 대상 
- Young/Old 세대로 분할  | 
| └ Young Generation | 새로운 객체가 생성되는 영역 | 
 - Eden, Survivor 구역 
 | 
| └ Old Generation | 장기 생존 객체 저장 | 
 - Full GC 대상 
 | 
| └ TLAB | 각 스레드 전용의 객체 할당 공간 | 
 - 동시 할당 충돌 방지, 성능 향상 목적 
 | 
| JVM 스택 | 메서드 호출 시마다 생성되는 스레드 기반 스택 | - 스택 프레임 단위 구성 | 
| └ 지역 변수 테이블 | 메서드 내 지역 변수 저장 | 
 - 32bit 슬롯 단위 
- 기본 타입, 참조, 반환 주소 등 저장  | 
| └ 피연산자 스택 | 계산에 필요한 값 임시 저장 | 
 - 연산 명령어 실행 시 사용됨 
 | 
| └ 동적 링크 및 반환 주소 | 메서드 호출/복귀 정보 유지 | 
 - 호출자와 피호출자 간 연결 정보 
 | 
| 프로그램 카운터 (PC) | 현재 스레드가 실행 중인 바이트코드의 줄 번호를 저장 | 
 - 스레드마다 별도 존재 
- 네이티브 메서드 실행 시 비어 있음  | 
| 네이티브 메서드 스택 | C 등의 네이티브 메서드 실행용 스택 | 
 - JNI 등 호출 시 사용 
 | 
2. 핫스팟 가상 머신에서의 객체 들여다보기
객체 생성
| 단계 | 설명 | 
 추가 설명 또는 처리 방식 
 | 
| 1. 심벌 참조 확인 | new 명령어의 대상이 상수 풀에 존재하는 클래스 심벌인지 확인 | 
 상수 풀에 해당 클래스에 대한 참조 존재 여부 
 | 
| 2. 클래스 로딩 여부 확인 | 해당 클래스가 이미 로딩되어 있는지 검사 | 
 로딩되지 않았다면 다음 단계로 진행 
 | 
| 3. 클래스 로딩 | 클래스 바이트코드를 메모리로 읽어 들임 | 
 로딩 → 링크(검증, 준비, 해석) → 초기화 순 
 | 
| 4. 메모리 할당 | 객체 인스턴스를 저장할 공간을 힙에서 확보 | 
 TLAB 또는 동기화된 공용 영역 사용 
 | 
| 5. 객체 구조 초기화 | 생성된 객체에 필수 메타정보 설정 | 
 클래스 포인터, 해시코드, GC 나이 등 
 | 
객체 메모리 레이아웃
| 구성 요소 | 설명 | 
 주요 내용 및 목적 
 | 
| 객체 헤더 | JVM이 객체를 관리하기 위해 추가하는 메타데이터 블록 | 
 마크 워드, 클래스 워드, (배열의 경우 배열 길이 포함) 
 | 
| └ 마크 워드 | 객체의 런타임 상태 정보 저장 | 
 해시코드, GC 나이, 락 상태, 타임스탬프 등 
 | 
| └ 클래스 워드 | 클래스 메타데이터를 가리키는 포인터 | 
 해당 객체가 어떤 클래스의 인스턴스인지 알려줌 
 | 
| └ 배열 길이 | 배열인 경우만 존재 | 
 배열의 요소 개수 저장 
 | 
| 인스턴스 데이터 | 실제로 객체가 담고 있는 필드 값 영역 | 
 부모 → 자식 클래스 순서 
타입 크기 순 정렬 (→ 메모리 효율 최적화)  | 
| 정렬 패딩 | 접근 성능 향상을 위한 빈 공간 | 
 8바이트 정수배로 맞추기 위해 존재 
 | 
객체 접근
| 항목 | 다이렉트 포인터 방식 | 핸들 방식 | 
| 구조 | 객체 참조가 힙의 객체 주소를 직접 가리킴 | 
 객체 참조가 핸들 테이블의 엔트리를 가리킴 
핸들은 실제 객체 주소와 클래스 주소를 포함  | 
| 접근 속도 | 빠름 (중간 참조 없음) | 
 느림 (간접 참조 필요) 
 | 
| GC 시 객체 이동 | 참조 주소 갱신 필요 | 
 핸들만 유지하면 참조 변경 없음 
 | 
| 참조 안정성 | 낮음 (객체 이동 시 참조 오류 가능) | 
 높음 (핸들이 추상화 계층으로 보호함) 
 | 
3. OutOfMemory 예외
| 오버플로 종류 | 발생 조건/설명 | 관련 JVM 옵션 | 
| 힙 오버플로 | 객체를 담을 힙 공간 부족 | -Xms: 최소 힙 크기 지정 -Xmx: 최대 힙 크기 지정 -XX:+HeapDumpOnOutOfMemoryError: OOM 발생 시 힙 덤프 생성  | 
| 네이티브 메서드 스택 오버플로 | 스레드가 너무 깊은 호출을 할 경우 | -Xss: 스레드당 스택 크기 설정 | 
| 메서드 영역 & 런타임 상수 풀 | 메타스페이스 초과 | -XX:MetaspaceSize: 초기 메타스페이스 크기 -XX:MaxMetaspaceSize: 최대 메타스페이스 크기 -XX:MinMetaspaceFreeRatio: 최소 여유 공간 비율 설정  | 
| 네이티브 다이렉트 메모리 오버플로 | ByteBuffer.allocateDirect() 사용 시 설정된 한도 초과 | -XX:MaxDirectMemorySize: 다이렉트 메모리 최대 사용량 제한 | 
출처
'Java' 카테고리의 다른 글
| [JVM 밑바닥까지 파헤치기] 3-2. 가비지 컬렉터와 메모리 할당 전략: 가비지 컬렉션 (0) | 2024.12.21 | 
|---|---|
| [JVM 밑바닥까지 파헤치기] 3-1. 가비지 컬렉터와 메모리 할당 전략: 회수 (1) | 2024.12.19 | 
| [JVM 밑바닥까지 파헤치기] 1. 자바 기술 시스템 소개 (3) | 2024.12.19 | 
| [Java][Tutorial] 1-3. Learning the Java Language: Classes and Objects (0) | 2024.01.14 | 
| [Java][Tutorial] 1-2. Learning the Java Language: Language Basics (0) | 2024.01.14 |