Java

[JVM 밑바닥까지 파헤치기] 6-1. 클래스 파일 구조: 클래스 파일

noahkim_ 2024. 12. 22. 13:48

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

 

1. 클래스 파일 (.class)

  • 하나의 클래스 또는 인터페이스의 구조와 바이트코드를 담고 있는 파일 (빅 엔디언 방식)
  • ✅ JVM이 실행할 수 있도록 컴파일된 결과물
  • 하위 호환성을 유지하며 확장됨 (최신 JVM 버전에서도 항상 실행됨)

 

메모리 저장 방식) 빅 엔디언

더보기
  • 가장 큰 자리를 먼저 저장하는 방식 (사람이 읽는 방식과 같음)
  • 네트워크 바이트 오더
  • ex) 0x1234 → 12 34

 

2. 구조

항목 설명 특징
매직 넘버 파일 형식을 식별하기 위한 고정 값 값은 0xCAFEBABE로 고정됨
버전 번호 이 클래스 파일이 어떤 JVM 스펙에 맞춰 생성되었는지 나타내는 값 실행 가능 여부를 결정함
상수 풀 클래스에서 사용하는 모든 상수와 심볼 참조를 저장하는 테이블
심벌 참조, 리터럴 상수 저장소
접근 플래그
클래스/인터페이스의 접근 수준
e.g) ACC_PUBLIC, ACC_FINAL
클래스 인덱스 현재 클래스와 부모 클래스를 가리키는 인덱스
상수 풀 인덱스로 클래스 이름을 찾음
필드 테이블
클래스에 정의된 멤버 변수들의 정보 저장
e.g) 이름, 타입, 접근 플래그 등
메서드 테이블
클래스에 정의된 메서드들에 대한 정보 저장
 
속성 테이블
각 필드/메서드/클래스의 속성 저장
e.g) Code, LineNumberTable

 

예시) 클래스 파일 구조

더보기
ClassFile {
    u4 magic;                          // 매직 넘버 (0xCAFEBABE)
    u2 minor_version;                  // 클래스 파일의 마이너 버전
    u2 major_version;                  // 클래스 파일의 메이저 버전
    u2 constant_pool_count;            // 상수 풀 항목의 개수
    cp_info constant_pool[constant_pool_count-1];  // 상수 풀 테이블
    u2 access_flags;                   // 접근 플래그 (public, final 등)
    u2 this_class;                     // 현재 클래스 정보 (상수 풀 인덱스)
    u2 super_class;                    // 슈퍼 클래스 정보 (상수 풀 인덱스)
    u2 interfaces_count;               // 구현된 인터페이스 개수
    u2 interfaces[interfaces_count];   // 인터페이스 목록 (상수 풀 인덱스)
    u2 fields_count;                   // 필드 개수
    field_info fields[fields_count];   // 필드 테이블
    u2 methods_count;                  // 메서드 개수
    method_info methods[methods_count];// 메서드 테이블
    u2 attributes_count;               // 속성 개수
    attribute_info attributes[attributes_count];   // 속성 테이블
}

 

예시) 필드/메서드 테이블 구조

더보기
struct {
    u2 access_flags;
    u2 name_index;
    u2 descriptor_index;
    u2 attributes_count;
    attribute_info attributes[attributes_count];
}
  • access_flags: 접근 제어자 + 특성 정보 (ACC_PUBLIC, ACC_PRIVATE, ACC_STATIC, ACC_SYNCHRONIZED)
  • name_index: 상수 풀의 CONSTANT_Utf8 인덱스
  • descriptor_index: 타입 정보를 표현하는 문자열

 

예시) 속성 테이블

더보기
struct {
    u2 attribute_name_index;
    u4 attribute_length;
    u1 info[attribute_length]; // 실제 속성 데이터
}
  • attribute_name_index: 상수 풀의 CONSTANT_Utf8 인덱스 (속성의 이름을 문자열로 참조함)
  • attribute_length: 해당 attrubute의 실제 바이트 길이
  • info[]: 실제 속성 데이터 (attribute마다 내부 구조 완전 다름)

 

표) descriptor_index 타입 정보

더보기
자바 타입 디스크립터
int I
long J
double D
boolean Z
String Ljava/lang/String;
int[] [I
메서드 (I)Ljava/lang/String;

 

표) attribute 종류

더보기
Attribute 이름 적용 위치 역할 중요 포인트
Code 메서드 실제 바이트코드 저장 JVM이 실행하는 코드가 여기 있음
LineNumberTable Code 내부 바이트코드 ↔ 소스 줄 번호 매핑 디버깅용
LocalVariableTable Code 내부 로컬 변수 이름/범위 정보 디버깅용
StackMapTable Code 내부 타입 검증 정보 바이트코드 검증에 필수
SourceFile 클래스 원본 .java 파일명 디버깅 정보
ConstantValue 필드 static final 상수 값 저장 컴파일 타임 상수
Exceptions 메서드 throws 목록 예외 선언 정보
Signature 클래스/필드/메서드 제네릭 타입 정보 런타임에는 소거되지만 여기 저장됨
InnerClasses 클래스 내부 클래스 정보 컴파일러 생성 메타데이터
EnclosingMethod 클래스 익명/로컬 클래스 외부 메서드 정보 람다/익명 클래스 관련
RuntimeVisibleAnnotations 클래스/필드/메서드 런타임 유지 애노테이션 리플렉션 가능
RuntimeInvisibleAnnotations 클래스/필드/메서드 컴파일 전용 애노테이션 런타임에는 제거
AnnotationDefault 메서드 애노테이션 기본값 애노테이션 정의 시 사용
BootstrapMethods 클래스 invokedynamic 부트스트랩 정보 람다/스트림 핵심
Module 클래스 Java 9 모듈 정보 JPMS 지원
Record 클래스 Java Record 메타정보 Java 14+
NestMembers / NestHost 클래스 중첩 클래스 접근 제어 Java 11+

 

표) 상수 풀

더보기
구분 설명 예시
리터럴
문자열, 숫자 값 등 고정 리터럴 값
- CONSTANT_Integer
- CONSTANT_Long
- CONSTANT_Utf8
심볼 참조
문자열 기반의 참조 정보
- CONSTANT_Class
- CONSTANT_Methodref
- CONSTANT_Fieldref
- CONSTANT_InterfaceMethodref
- CONSTANT_NameAndType
동적 링크
런타임 중 클래스 로딩/링크에 필요한 참조
- CONSTANT_MethoHandler
- CONSTANT_MethoType
- CONSTANT_InvokeDynamic (람다)