저우즈밍 님의 "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 |