[ Java ] Class Loader

NaHyun_kkiimm·2024년 3월 21일
0

Java

목록 보기
3/3

Class Loader

: JVM 내로 클래스 파일(*.class)을 로딩하고, 링크를 통해 배치하는 작업을 수행하는 모듈

  • Exection Engine이 사용할 수 있도록 JVM 메모리에 적재하는 역할을 수행한다.
  • LoadingLinkingInitialization 단계로 진행한다.
[ JVM 상에서 Java Application이 구동되는 방법 요약 ]

실행 중에 필요한 .class 파일을 Runtime Data Areas에 로드하고,
Execution Engine이 바이트 코드를 실행한다.

1. 로딩 [ Loading ]

: .class 파일을 JVM Method 영역에 저장한다.

  • 동적 로딩(Dynamic Loading)을 하기 때문에, static변수나 실행하지 않는 클래스는 로드되지 않는다.
    • JVM의 시작과 함께 클래스가 로드되면, 모든 정적 블록이나 필드는 JVM에 로드되기 때문
  • Method Area에 저장되는 데이터
    • 클래스의 type 정보(Class, Interface, Enum 등)
    • 클래스의 Method, 변수
    • Fully-Qualified Class Name (Ex. java.lang.Character$Subset) : 클래스가 속한 패키지명을 모두 포함한 이름

로딩 순서

(1) JVM의 Method Area에 클래스가 로드되어 있는지 확인

- 있다면, 해당 클래스 사용
- 없다면, Class Loader에 요청

(2) `Application Class Loader` → `Extension Class Loader` → `Bootstrap Class Loader` 순으로 요청을 위임한다.

(3) `Bootstrap Class Loader`는 Bootstrap Classpath(`JDK`/`JRE`/`LIB`)에 해당 클래스가 있는지 확인

- 없다면, Extension Class Loader에게 요청 위임

(4) `Extension Class Loader`는 Extension Classpath(`JDK`/`JRE`/`LIB`/`EXT`)에 해당 클래스가 있는 확인

- 없다면, Application Class Loader에게 요청 위임

(5) `Application Class Loader`는 환경 변수로 지정된 Classpath에 해당 클래스가 있는지 확인

- 없다면, `ClassNotFoundException` 예외를 발생시킨다.   

ClassPath : JVM이 시스템 모든 폴더를 검사할 수 없으므로, JVM에 파일 경로를 제공해야 한다.

클래스 로더의 종류

1) Bootstrap Class Loader
: 자바에서 기본적으로 제공하는 API 등과 같은 표준 JDK 클래스들을 로드한다.

- JVM 시작 시, 가장 최초로 실행되는 클래스 로더
- `JRE/LIB` 디렉토리에 있는 핵심 라이브러리와 `java.lang.Object`, `java.lang.ClassLoader`와 같은 최소한의 클래스만 로드한다.
2) Extension Class Loader
: `JRE/LIB/EXT`나 환경 변수 `java.ext.dirs`에 지정된 경로(확장 디렉토리)에서 클래스를 로드한다.

- Java 9 : 확장 매커니즘이 제거됨. 클래스 이름 변경 (`ExtClassLoader` → `PatformClassLoadere`)
3) Application Class Loader
: Class Path로 지정한 경로에서 클래스를 로드한다. ⇒ 우리가 만든 `.class` 확장자 파일을 로드한다.

System Class Loader라고도 부른다.

2. 링크 [ Linking ]

: .class 파일을 사용하기 위해 검증하는 과정

(1) 검증 [ Vertify ] : 읽어 들인 클래스가 자바 언어 명세 및 JVM 명세에 명시된 대로 구성되어 있는지 검사
  • 검증 실패 시, 런타임 에러(java.lang.VertifyError) 발생
(2) 준비 [ Prepare ] : 클래스가 필요로 하는 메모리를 할당하고, 클래스에서 정된 필드, 메소드, 인터페이스를 나타내는 데이터 구조를 준비한다.
  • 메모리를 할당하고, static 필드가 기본값으로 초기화된다.
(3) 분석 [ Resolve ] : Class의 Constant Pool내의 모든 심볼릭 레퍼런스를 실제 메모리 레퍼런스로 교체한다.

심볼릭 레퍼런스 : 메모리 번지가 아닌 이름에 의한 참조

3. 초기화 [ Initialization ]

: 링크 단계에서 확보한 메모리 영역에 클래스 변수(static 변수)을 명시된 값으로 할당한다.


동적 로딩 [ Dynamic Class Loading ]

1) Load-Time Dynamic Loading

: 하나의 클래스를로딩하는 과정에서 동적으로 다른 클래스를 로딩하는 것

public class Main {
	public static void main(String[] args) {
		System.out.println("Hello World!");
	}
}

(1) JVM이 시작되고, Bootstrap Class LoaderObject 클래스를 로드한다.
→ Object 클래스는 모든 클래스를 상속하기 떄문
(2) Main class를 로딩하기 위해 Main.class 파일을 로드한다.
(3) Main 클래스를 로드하는 과정에서 필요한 클래스인 java.lang.Stringjava.lang.System을 로드한다.
→ 로드하는 과정에서 필요한 다른 클래스 로드. 즉, 동적 로딩 발생

2) Run-Time Dynamic Loading

: 클래스를 로드하는 것이 아닌, 코드를 실행하는 순간 클래스를 로드하는 것

public class RuntimeLoading {
	public static void main(String[] args) {
		try {
			Class cls = Class.forName(args[0]);
			Object obj = cls.newInstance();
			Runnable r = (Runnable) obj;
			r.run();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

(1) Class.forName() 메서드가 실행되기 전까지 RuntimeLoading 클래스에서 어떤 클래스를 참조했는지 알 수 없다.
→ 명령형 인수(args[0])로 전달된 클래스 일믕르 알 수 없기 때문
(2) 따라서, RuntimeLoading 클래스를 로딩할 때에는 어떤 클래스도 로딩하지 않고, Class.forName(args[0])이 호출되는 순간 args[0]에 해당하는 클래스를 로딩한다.

Class.forName(): 컴파일 타임에 직접적인 참조 없이 런타임에 동적으로 클래스를 로드하기 위함으로 사용된다.

  • 물리적인 클래스 파일명을 인자로 넣으면, 이에 해당하는 클래스를 반환해주는 역할을 수행한다.

참고

JVM Class LaodeR(클래스 로더) 동작 과정

[JAVA] JVM - Class Loader


오늘의 한마디
  • 항상 초심과 기본기를 잃지 말자
  • 세상에 절대 할 수 없는 일은 아동복 모델 밖에 없다.
profile
이 또한 지나가리라

0개의 댓글

관련 채용 정보