클래스로더
클래스 로더는 JVM 내로 클래스 파일(*.class)을 동적으로 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈이다.
컴파일 단계 : complier에 의해 .class 바이트코드로 파일이 변환된다.
런타임 단계 : 런타임(bytecode를 실행할 때) 이 .class 파일을 로드하고 링크한다.
즉, 런타임 단계에서 로드된 바이트 코드(.class)들을 엮어서 JVM의 메모리 영역인 Runtime Data Areas에 배치한다.
클래스를 메모리에 올리는 로딩 기능은 한번에 메모리에 올리지 않고, 어플리케이션에서 필요한 경우 동적으로 메모리에 적재하게 된다.
클래스 파일의 로딩 순서
JVM에서 클래스를 로드하고 실행하는 과정은 크게 로딩(Loading), 링크(Linking), 초기화(Initialization)의 세 단계로 구분할 수 있다.
이 중 링크 단계는 검증(Verification), 준비(Preparation), 분석(Resolution)의 세부 단계로 더 세분화된다.
로딩(Loading)
- 클래스로더가 클래스파일(.class)을 읽어와 JVM의 메모리에 클래스를 로드하는 과정이다.
- 클래스 로더는 파일 시스템, 네트워크, 또는 다른 소스로부터 클래스의 바이트코드를 찾아서 JVM 내부의 런타임 데이터 영역에 로드한다.
링크(Linking)
링크 단계는 검증, 준비, 분석의 세부 단계로 나뉜다.
검증(Verification)
로드된 클래스의 바이트코드가 JVM의 명세에 맞게 잘 형성되어 있는지 검증하는 과정
동작: 바이트코드의 형식, 구조를 검사하고, 논리적으로 일관성이 있는지 확인한다.
목적: 안전하지 않은 코드가 JVM을 손상시키지 않도록 방지한다.
준비(Preparation)
클래스 또는 인터페이스에 필요한 메모리를 할당하는 과정
동작: 클래스 변수(static fields)에 대한 메모리를 할당하고, 이 변수들에 대한 기본값을 설정한다.
목적: 클래스나 인터페이스가 사용될 때 필요한 데이터 구조를 메모리에 준비한다.
분석(Resolution)
클래스 파일 내의 심볼릭 메모리 참조를 직접 참조로 변환하는 과정
동작: 클래스, 인터페이스, 필드, 메서드에 대한 참조가 실제 메모리 주소로 연결된다.
목적: 클래스의 코드가 다른 클래스나 자원을 실제로 참조할 수 있도록 한다.
심볼릭 링크(symbolic link) 란? - 링크를 연결하여 원본 파일을 직접 사용하는 것과 같은 효과를 내는 링크이다. 윈도우의 바로가기와 비슷한 개념.
클래스 로더의 종류
부트스트랩 클래스 로더 (Bootstrap Class Loader)
- JVM이 가장 먼저 사용하는 클래스 로더다.
- 자바의 기본 클래스(예: java.lang.Object)를 로드하는 책임을 가진다.
=> 가장 기초적인 부분만을 로드한다. - JAVA_HOME/jre/lib에 위치한 코어 자바 API를 로드한다.
- C++로 구현되어 있어 자바 코드에서 직접 참조할 수 없다.
- 가장 최상위에 위치한 클래스 로더로, 다른 클래스 로더의 부모가 될 수 없다.
확장 클래스 로더 (Extension Class Loader)
- 부트스트랩 클래스 로더의 자식이며, 표준 코어 자바 클래스 외의 확장 클래스를 로드한다.
- JAVA_HOME/jre/lib/ext 폴더나 java.ext.dirs 시스템 프로퍼티로 지정된 위치에 있는 클래스를 로드한다.
- 주로 자바 플랫폼의 일부가 아니지만, 많은 자바 애플리케이션에서 사용되는 확장 라이브러리를 로드하는데 사용된다.
- 자바로 구현되어 있어 자바 코드에서 참조 가능하다.
애플리케이션(시스템) 클래스 로더 (Application(System) Class Loader)
- 확장 클래스 로더의 자식이며, 애플리케이션의 클래스를 로드한다.
- 애플리케이션 클래스패스(-cp 또는 -classpath 옵션으로 지정)에 있는 클래스를 로드한다.
- 일반적으로 개발자가 작성한 코드와 라이브러리를 로드하는 데 사용된다.
- 이 로더로부터 시작하여 자바의 클래스 로딩은 위임 모델을 따른다. 즉, 시스템 클래스 로더는 클래스 로딩 요청을 먼저 확장 클래스 로더에게 위임하고, 확장 클래스 로더는 부트스트랩 클래스 로더에게 위임한다. 필요한 클래스를 찾지 못하면 각자의 로딩 순서에 따라 클래스를 로드한다.
클래스로더의 3가지 원칙
위임 모델(Delegation Model)
1. 클래스로더는 클래스를 로드할 때 먼저 자신의 부모 클래스로더에게 해당 클래스를 로드할 기회를 제공한다.
2. 이 과정은 최상위인 부트스트랩 클래스로더에 이르기까지 반복된다. (가장 부모인 클래스로더)
3. 만약 부트스트랩 클래스로더까지 가서도 해당 클래스를 찾을 수 없는 경우, 원래 클래스로더가 직접 클래스를 로드하려고 시도한다.
이러한 위임 모델은 Java의 클래스 로딩 메커니즘에서 클래스의 유일성과 보안을 보장하는 데 중요한 역할을 합니다.
최상위 부모로부터 하위 자식 클래스 로더로 이동하며, 이를 통해 JVM 내에서 클래스가 중복 로드되는 것을 방지한다.
가시성 원칙(Visibility Principle)
자식 클래스로더는 부모 클래스로더의 네임스페이스를 참조할 수 있으나, 부모 클래스로더는 자식 클래스로더의 네임스페이스를 확인하거나 참조할 수 없다.
이는 클래스로더의 위임 모델에 따라, 클래스 로딩 요청이 발생하면 자식 클래스로더가 먼저 부모 클래스로더에게 해당 클래스의 로딩을 위임하기 때문이다. (위임 모델 사용)
이 원칙을 클래스 로딩 환경의 격리를 가능하게 하며, 보안과 효율성을 높이는 데 기여한다.
유일성 원칙(Uniqueness Principle)
위임 모델 덕분에, JVM 내에서 하나의 클래스는 특정 클래스 로더에 의해 단 한 번만 로드될 수 있다. 이 원칙은 클래스의 유일성을 보장한다.
ref
https://leeyh0216.github.io/posts/java_class_loader/
https://steady-coding.tistory.com/593
'CS study > java' 카테고리의 다른 글
[troubleshooting][ClassLoader]동적 클래스로더와 계층 관계 (0) | 2024.04.02 |
---|---|
[JVM]JVM과 ClassLoader 그리고 JIT의 관계 (0) | 2024.04.02 |
함수형 프로그래밍 패러다임 (0) | 2024.03.24 |
람다(Lambda)식의 정의와 함수형 인터페이스, 메서드 참조 (1) | 2024.03.23 |
[DataSource]HikariCP DataSource 연동 과정 및 구현체 (0) | 2024.02.28 |