저우즈밍 님의 "JVM 밑바닥까지 파헤치기" 책을 정리한 포스팅 입니다
0. 동적 로딩
- 런타임에서 클래스가 필요할 때 클래스가 jvm에 동적으로 로드되는 방식
- 런타임에 클래스 로딩 → 링킹 → 초기화가 순차적으로 수행됨
장점
항목 | 설명 |
확장성 |
필요할 때만 클래스를 로딩
→ 모듈화 및 유연한 설계 가능 |
유연성 |
특정 클래스나 기능을 런타임 중에 교체/추가 가능
|
외부 소스 로딩 |
네트워크/파일시스템 등에서 외부 .class를 로드할 수 있음
|
런타임 바인딩 |
컴파일 타임이 아닌 실행 시 클래스 결정 가능 → 플러그인 구조에 유리
|
단점
- 성능 떨어짐
1. Loading
- 클래스의 바이트코드를 읽어와 JVM 메모리에 로드하는 단계
- 바이트 스트림을 런타임 데이터 구조로 변환해 메서드 영역에 저장하고, Heap에 Class 객체 생성
특징
항목 | 설명 |
클래스 로더 사용 |
- JVM 내장: 부트스트랩 클래스 로더
- 사용자 정의 가능: ClassLoader의 findClass() 또는 loadClass() 오버라이딩 |
배열 클래스 제외 |
- 배열 클래스는 클래스 로더가 아닌 JVM이 직접 생성 (동적 생성 구조)
|
Class 객체 생성 |
- Heap에 java.lang.Class 인스턴스 생성
- 이는 해당 클래스의 런타임 표현 객체 역할 수행 |
메서드 영역 저장 |
- 타입 정보는 메서드 영역에 저장되며 Class 객체가 이를 참조하여 사용
|
2. Linking
과정
단계 | 설명 | 항목 |
Verification |
바이트코드가 JVM 명세를 정상적으로 따르고 있는지 확인
→ 실행 안전성 확보 목적 |
- 파일 형식: 매직 넘버 버전 번호, 상수 타입 유효성 등
- 메타데이터: 상위 클래스 존재 여부, 필드 이름 충돌 여부 - 바이트코드 유효성: 명령어 유효성, 형변환 적절성 - 접근 제어: 심벌 참조 대상의 접근 권한 확인 |
Preparation |
클래스 변수의 메모리 할당 및 초기화 (디폴트 값)
|
|
Resolution |
상수 풀의 심벌 참조를 실제 메모리 주소의 직접 참조로 변환
|
|
3. Initialization (Optional)
- 클래스의 정적(static) 초기화 코드인 <clinit> 메서드를 실행하는 단계
- 클래스가 최초로 사용될 때 단 한 번만 실행됨
동작 흐름
항목 | 설명 |
<clinit> 실행 |
컴파일러가 자동 생성하는 클래스 초기화 메서드(정적 필드 초기값 + static 블록 내용 포함)
|
부모 클래스 우선 |
상위 클래스의 <clinit>이 먼저 실행되고, 그 다음에 현재 클래스의 <clinit> 실행
|
실행 조건 |
아래 조건 중 하나라도 발생 시 실행됨:
▪ new (인스턴스 생성) ▪ getstatic, putstatic (정적 필드 접근/수정) ▪ invokestatic (정적 메서드 호출) |
'Java' 카테고리의 다른 글
[JVM 밑바닥까지 파헤치기] 7-3. 클래스 로딩 매커니즘: 자바 모듈 시스템 (3) | 2024.12.23 |
---|---|
[JVM 밑바닥까지 파헤치기] 7-2. 클래스 로딩 매커니즘: 클래스 로더 (0) | 2024.12.23 |
[JVM 밑바닥까지 파헤치기] 6-2. 클래스 파일 구조: 바이트코드 명령어 (2) | 2024.12.22 |
[JVM 밑바닥까지 파헤치기] 6-1. 클래스 파일 구조: 클래스 파일 (0) | 2024.12.22 |
[JVM 밑바닥까지 파헤치기] 3-5. 가비지 컬렉터와 메모리 할당 전략: 저지연 가비지 컬렉터 (0) | 2024.12.21 |