ClassLoader의 전체적인 역할Loading실습1. Bootstrap Class Loader2. Extensions ClassLoader3. Application ClassLoaderClassLoader의 구현 구조LinkingInitialization
[ Tecoble ] JVM에 관하여 — Part2, ClassLoader
역할
: Java Compiler를 통해 .class 확장자를 가진 클래스 파일은 각 디렉터리에 흩어져 있고, 기본 라이브러리의 클래스 파일들은 $JAVA_HOME 내부 경로에 존재함
⇒ 각각의 클래스 파일들을 찾아서 JVM의 메모리에 탑재 해주는 역할을 하는 것이 ClassLoader의 역할임
ClassLoader의 전체적인 역할
- ClassLoader는 클래스 파일을 찾아서 탑재하는 역할 뿐 아니라 JVM에 관련된 다른 일들도 같이하게 됨
- 크게, Loading, Linking, Initialization 3가지 역할을 맡음
- Loading : 클래스 파일을 탑재하는 과정
- Linking : 클래스 파일을 사용하기 위해 검증, 기본 값으로 초기화하는 과정
- Initialization : static field의 값들을 정의한 값으로 초기화를 하는 과정
Loading

- ClassLoader 가 필요한 클래스 파일들을 찾아 탑재함. 각각의 클래스 파일들이 기본으로 제공받는 클래스 파일인지 혹은 개발자가 정의한 클래스 파일인지와 같은 기준에 따라
ClassLoader
의 수준이 세 가지로 나뉨
실습
import java.util.LinkedList; import java.util.List; public class Main { public static void main(String[] args) { UserClass userClass = new UserClass(2); int number = 1; List<Integer> numbers = new LinkedList<>(); } } public class UserClass { private int num; public UserClass(int num) { this.num = num; } public int getNum() { return num; } }
java -verbose:class Main
1. Bootstrap Class Loader
- 다른 모든 ClassLoader의 부모가 되는 ClassLoader임
- rt.jar를 포함하여 JVM을 구동시키기 위한 가장 필수적인 라이브러리의 클래스들을 JVM에 탑재함
- 가장 상위의 ClassLoader이므로 다른 ClassLoader와는 다르게 탑재되는 운영체제에 맞게 네이티브 코드로 작성됨
[Opened /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar] [Loaded java.lang.Object from /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar] [Loaded java.io.Serializable from /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar] ...중략...
2. Extensions ClassLoader
- Bootstrap ClassLoader 다음으로 우선순위를 가지는 ClassLoader임
- localedata, zipfs 등 다른 표준 핵심 Java Class의 라이브러리들을 JVM에 탑재하는 역할을 함
- 이들은, $JAVA_HOME/jre/lib/ext__ 에 있음
3. Application ClassLoader
- System ClassLoader 라고도 부름
Classpath
에 있는 클래스들을 탑재함
- 개발자들이 자바 코드로 짠 클래스 파일들을 JVM에 탑재하는 역할을 수행
ClassLoader의 구현 구조
public class Main { public static void main(String[] args) { UserClass userClass = new UserClass(2); System.out.println("Application ClassLoader: " + UserClass.class.getClassLoader()); System.out.println("Extension ClassLoader: " + UserClass.class.getClassLoader().getParent()); System.out.println("Bootstrap ClassLoader: " + UserClass.class.getClassLoader().getParent().getParent()); } } /* Application ClassLoader: sun.misc.Launcher$AppClassLoader@75b84c92 Extension ClassLoader: sun.misc.Launcher$ExtClassLoader@4aa298b7 Bootstrap ClassLoader: null */
Linking
- 로드된 클래스 파일들을 검증하고 사용할 수 있게 준비하는 과정을 의미함
Linking
또한Verification
,Preparation
,Resolution
이라는 세 가지 단계로 이루어져 있음
Verification (클래스 파일 유효성 검증)
클래스 파일이 유효한지를 확인하는 과정. 클래스 파일이 JVM의 구동 조건대로 구현되지 않았을 경우에는 VerifyError를 던지게 됨
Preparation (메모리 할당 & 기본값으로 초기화)
- 클래스 및 인터페이스에 필요한 static field 메모리를 할당하고, 이를 기본값으로 초기화를 함
- 기본값으로 초기화된 static field 값들은 뒤의 Initialization 과정에서 코드에 작성한 초기값으로 변경됨
- 이 때문에 JVM에 탑재된 클래스 파일의 코드를 작동시키지는 않음
Resolution
Symbolic Reference
값을 JVM의 메모리 구성요소인Method Area
의 런타임 환경 풀을 통하여Direct Reference
라는 메모리 주소 값으로 바꾸어줌
- 해당 단게의 영향을 받는 JVM Instruction 요소는
new
및instanceof
가 있음
Initialization
- 클래스 파일의 코드를 읽음
- Java 코드에서의 class와 interface의 값들을 지정한 값들로 초기화 및 초기화 메서드를 실행시켜줌
- 이 때, JVM은 멀티 스레딩으로 작동을 하며, 같은 시간에 한 번에 초기화를 하는 경우가 있기 때문에, 초기화 단계에서도 동시성을 고려해주어야 함