클래스 로더 (Class Loader)
클래스 로더(Class Loader)는 Java 가상 머신(JVM)에서 클래스를 동적으로 로드하는 역할을 한다. 클래스 로더는 JVM이 애플리케이션을 실행할 때 필요한 클래스를 메모리에 로드하고, 이를 초기화하는 과정을 담당한다.
JVM은 애플리케이션 실행 시 필요한 모든 클래스를 미리 로드하지 않고, 필요할 때마다 동적으로 로드하기 때문이다.
따라서 클래스 로드는 Java 애플리케이션의 유연성과 확장성을 높이는 중요한 역할을 한다.
클래스 로더의 종류
- 부트스트랩 클래스 로더 (Bootstrap Class Loader)
- JVM의 기본 라이브러리(rt.jar, tools.jar 등)를 로드한다.
- 일반적인 자바 코드가 아닌 C++로 구현되어 있다.
- BIOS처럼 JVM의 초기 부팅 역할을 한다고 생각하면 된다.
- 플랫폼 클래스 로더 (Platform Class Loader, 기존 확장 클래스 로더)
- Java 9 이전: ExtClassLoader
- Java 9 이후: PlatformClassLoader
- JDK의 확장 라이브러리를 로드한다. (예: lib/ext 디렉터리)
- 애플리케이션 클래스 로더 (Application Class Loader)
- 애플리케이션에서 작성한 사용자 클래스(classpath에 있는 클래스들)를 로드한다.
- ClassLoader 클래스의 기본 구현체
자바 클래스 로딩 과정
클래스 로더에서 class 파일을 로딩하는 순서는 다음과 같다.
- Loading(로딩) : 클래스 로더가 클래스 파일(`. class`)을 가져와서 JVM의 메모리의 로드한다.
- Linking(링킹) : JVM에 로드된 클래스를 검증, 준비, 해석한다. (파일을 사용하기 위해 검증하는 과정)
- Initialization(초기화) : 클래스 변수들을 적절한 값으로 초기화한다.
1. Loading(로딩)
로딩이란 말 그대로 `.class`파일을 JVM의 메모리에 올리는 단계이다. 클래스 로더가 주도적인 역할을 수행한다.
클래스 로더는 `.class`파일을 클래스패스(classpath)에서 찾거나 네트워크 등을 이용 외부 소스로부터 가져와 해당 클래스를 읽어 JVM 메타스페이스(Metaspace)에 클래스의 메타데이터를 저장한다.
- 로드된 클래스와 그 부모 클래스 정보
- 클래스 파일과 Class, Interface, Enum 관련 여부
- 변수나 메서드 정보
2-1. 링킹 - 클래스 검증 (Verification)
읽어온 `.class`파일이 자바 및 JVM 명세를 준수하는지 검증한다. 주요 검증 작업은 다음과 같다.
- .class 파일 형식의 유효성
- 바이트코드 명령어의 유효성
- 참조가 유효한 클래스, 메서드, 필드인지 확인
- 악성 코드나 보안 문제 방지
검증에 실패한다면 `java.lang.VerifyError`가 발생하게 된다.
2-2. 링킹 - 준비(Preparation)
준비 단계에서는 클래스 변수(정적 변수)를 위한 메모리 공간 할당 및 기본값으로 초기화한다.
- int는 0, boolean은 false, 참조 타입은 null로 초기화한다.
- 단, final로 선언된 변수는 코드에서 정의된 값으로 초기화한다.
이 단계에서 `java.lang.Class`객체가 생성된다. 이 객체는 로딩할 클래스의 메타 데이터를 가지고 있다. 메타데이터만 가지고 있다는 것은 결국 아직 힙영역에 인스턴스가 생긴 상태를 의미하는 것은 아니고 JVM 메타스페이스에서 유지된다. 쉽게 이야기하자면, 생성자 호출 전 상태(new 연산 전)라 이해하면 되고 로딩할 클래스의 인스턴스(힙 영역)는 초기화 단계에서 생성되게 된다.
2-3. 링킹 - 해석 (Resolution)
- 상수 풀(Constant Pool)의 심벌릭 참조(Symbolic Reference)를 직접 참조(Direct Reference)로 변환하는 과정이다.
- 심벌릭 참조: 메서드나 필드 이름
- 직접 참조: 실제 메모리 주소
3. 객체 생성 과정 (Heap 영역) - 초기화 단계(Initialization)
초기화 단계(Initialization)는 객체 생성 과정의 마지막 단계로, 생성자를 호출하여 객체의 상태를 최종적으로 설정하는 작업을 담당한다.
- 메모리 공간 할당: JVM은 Heap 영역에 객체를 저장할 메모리를 할당한다.
- 필드 초기화: 객체의 인스턴스 변수는 기본값(예: int는 0, boolean은 false, 참조 타입은 null)으로 초기화된다.
- 객체 헤더 설정: JVM은 객체 헤더에 클래스 메타정보, 해시코드, GC 세대 정보 등을 저장한다.
- 생성자 호출: 생성자를 실행하여, 프로그래머가 정의한 초기값으로 객체를 초기화한다.
단, 정적 변수(static 변수)는 링킹(Linking) 단계의 Preparation(준비) 과정에서 메모리를 할당받고 기본값으로 초기화된다. 초기화(Initialization) 단계에서 실제 값이 할당된다(코드에서 설정된 값으로 설정).
정리(답변)
클래스 로더(Class Loader)는 프로그램 실행 시 필요한 클래스를 동적으로 메모리에 로드하는 역할을 합니다.
이러한 동적 로딩은 자바의 유연성과 확장성을 높이며, 프로그램 실행 중에도 새로운 클래스를 로드하거나 교체할 수 있어 기능 확장이 용이합니다.
또한, 클래스 로더는 보안 측면에서도 중요합니다. 신뢰할 수 있는 소스에서만 클래스를 로드하여 악의적인 코드 실행을 방지합니다.
클래스 로더는 부트스트랩, 플랫폼, 애플리케이션의 계층 구조로 구성되어 있으며, 상위 로더가 클래스를 찾지 못할 경우 하위 로더가 순차적으로 클래스를 로드합니다.
이 구조를 통해 자바는 다음과 같은 특징을 실현합니다
- 동적 로딩: 필요한 시점에만 클래스를 로드하여 메모리 효율성을 높임
- 보안 강화: 신뢰할 수 없는 코드를 차단
- 유연한 확장성: 네트워크나 외부 소스에서 클래스를 동적으로 가져올 수 있음
결과적으로, 클래스 로더는 자바 애플리케이션의 안정적이고 효율적인 실행에 필수적인 요소입니다.
'Language > Java' 카테고리의 다른 글
[Java] 자바 예외 처리 - 예외 계층, 체크 예외, 언체크 예외, 예외의 규칙 (0) | 2025.01.31 |
---|---|
[Java] Class 클래스 (0) | 2025.01.30 |
[Java] Wrapper 클래스와 성능(오토 박싱 & 오토 언박싱) (0) | 2025.01.23 |
[Java] 불변객체 - String과 성능(StirngBuilder vs StringBuffer) (1) | 2025.01.22 |
[Java] 불변객체(Immutable Object) (0) | 2025.01.22 |