자바

[JVM] Class Loader 알아보기 - (1)

2023. 5. 16. 15:24
목차
  1. JVM 내부구조
  2. Class Loader
  3. Step 1 - 로딩(Loading)
  4. Step 2 - 링킹(Linking)
  5. Step 3 - 초기화(Initialization)
728x90

JVM 은 사용자 컴퓨터 운영체제에 맞는 JRE 에 포함되어 있는 소프트웨어로, 바이트 코드로 변환된 자바 코드를 실행시켜주는 역할을 한다.

자바 프로그램을 실행함에 있어 .class 파일에 대한 유효성 검사와 메모리 관리, GC 등의 작업을 수행하기 때문에 매우 중요한 소프트웨어라고 할 수 있다.

 

JVM 내부구조

JVM은 크게 다음과 같이 이루어져 있다.

 

  • 클래스 로더(class loader)
  • 실행 엔진(execution engine)
    • 인터프리터(interpreter)
    • JIT Compiler
    • 가비지 콜렉터(garbage collector)
  • 런타임 영역(runtime data area)

 

 

이번 글에서는 클래스 로더가 무엇이고, 어떻게 동작하는 지 알아보자.

 

 


Class Loader

 

클래스 로더는 위 그림에서 추측할 수 있듯이 자바 바이트 코드(.class)를 읽어 런타임 영역에 적재하는 역할을 한다.

중요한 것은 이 과정이 동적으로 이루어진다는 것인데, 이를 동적 로딩이라 한다.

이 과정에서 클래스 로더는 클래스 파일이 유효한지 검증하고, 필드 및 메서드를 초기화 하는 역할도 수행한다.

 

이 모든 과정을 다음과 같이 세 단계로 나눌 수 있다.

 

  1. 로딩(loading)
  2. 링크(linking)
  3. 초기화(initialization)

 

Step 1 - 로딩(Loading)

로딩 단계는 자바 프로그램 동작 중 필요한 클래스 파일들을 찾아 탑재하는 과정이다.

이 동작은 각각의 클래스 파일들이 JDK에 의해 기본적으로 제공받는 클래스 파일인지 혹은 개발자가 정의한 클래스 파일인지와 같은 기준에 의해 세 가지 Class Loader 로 나뉘어 실행된다.

 

1-1. Bootstrap Class Loader

JVM 이 시작되고 가장 최초로 실행되는 최상위 Class Loader 이다.

Bootstrap Class Loader 는 하위 Class Loader 와 최소한의 자바 클래스를 로드하는데, JDK 8 기준으로 jre/lib/rt.jar 에 위치한 자바 런타임 코어 클래스를 로드한다.

rt.jar 파일에는 java.lang, java.util 등과 같이 필수 패키지들이 들어있다.

Bootstrap Class Loader 는 가장 상위의 Class Loader 이므로 다른 Class Loader 와 다르게 탑재되는 운영체제에 맞게 Native Code 로 쓰여있다.

 

1-2. Extensions Class Loader 

Bootstrap Class Loader 다음으로 우선순위를 가지는 Class Loader 이다.

주로 jre/lib/ext 디렉토리나 java.ext.dirs 환경 변수로 지정한 디렉토리 안에 있는 클래스 파일을 로딩하며 JDK 확장 라이브러리들을 다룬다.

 

1-3. Application Class Loader 

자바 프로그램 실행 시 지정한 classpath 에 있는 클래스 혹은 Jar에 속한 클래스들을 로드한다.

주로 개발자들이 작성한 자바 코드 클래스 파일들을 탑재하는 역할을 하고 있다.

 

 

JDK 9 버전 이후 변경점

더보기

JDK 9 버전 이후 JDK 에 module 개념이 새롭게 탑재되며 기존 jre, ext 디렉토리 등이 삭제되고 해당 기능들은 작은 단위의 모듈로 분리되게 되었다. 이로 인해 자바 프로그램이 전체 JDK 를 실행하지 않도록 할 수 있어 더 효율적인 포맷으로 진화하였다.

 

이러한 변경점으로 인해 주요 Class Loader 들의 주요 기능이나 명칭도 변경되었다.

 

아래는 JDK 9 버전 이후의 변경점이다.

 

1-1. Bootstrap Class Loader

 - 기존에는 모든 Java SE 클래스들을 로드할 수 있었지만, rt.jar 가 모듈화 되어 작은 단위로 나눠지면서 java.base 같은 중요한 모듈의 클래스 로딩만 다루게 역할이 축소되었다.

 

2-2. Platform Class Loader

 - Extensions Class Loader 에서 명칭이 변경되었다.

 - Java SE 플랫폼에 있는 모든 클래스들에 대해 로더 역할을 수행할 수 있게 확장되었다.

 - Java SE 플랫폼에 속해있지 않은 표준화된 JCP(Java Community Process) 클래스에 대해서도 로더 역할을 할 수 있게 변경되었다.

 - 기존에는 URLClassLoader 를 상속받아 사용되고 있었지만 BuiltinClassLoader 를 상속받아 ClassLodaers 클래스의 내부 static 클래스로 구현되게 변경되었다.

(URLClassLoader 에 대한 자세한 설명은 https://homoefficio.github.io/2018/10/14/Java-URLClassLoader%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%A1%9C%EB%94%A9/)

 

2-3. System Class Loader

 - Application Class Loader 에서 명칭이 변경되었다.

 - 마찬가지로 기존에는 URLClassLoader 를 상속받아 사용되고 있었지만 BuiltinClassLoader 를 상속받아 ClassLodaers 클래스의 내부 static 클래스로 구현되게 변경되었다.

 - Java SE 나 JDK 모듈이 아닌 모듈들에 대해서도 default 로더 역할을 할 수 있게 변경되었다. 

 

 

Loading 동작 방식

Class Loader 는 다음과 같은 위임 방식으로 클래스들을 로딩한다.

 

System Class Loader -> Platform Class Loader -> Bootstrap Class Loader

 

요청한 클래스가 이러한 위임 과정을 거쳐 Class Loader 에 의해 로드가 되지 않는다면 java.lang.ClassNotFoundException 이 발생하겠지만, 로드에 성공한다면 내용에 맞는 바이너리 데이터를 생성한 뒤 메모리의 Method Area 에 저장한다.

그 후 Class<객체이름> 형태의 해당 클래스 타입의 class 객체를 생성해서 Heap 영역에 저장한다.

 

 

 

 

Step 2 - 링킹(Linking)

이 단계에서는 로드된 클래스나 인터페이스, 필요한 경우 요소 타입을 검증하고 사용할 수 있게 준비하는 과정을 포함한다.

이 작업은 Verification, Preparation, Resolution 이라는 세 단계로 이루어진다.

 

 

2-1. 검증(Verification)

클래스 로더가 .class 파일의 바이트코드를 자바 언어 명세서(Java Language Specification) 에 따라서 코드를 제대로 작성했는지, JVM 규격에 맞게 검증된 컴파일러에서 .class 파일이 생성되었는지 등을 확인하여 .class 파일의 정확성을 보장해준다.

내부적으로 바이트 코드 검증기(Bytecode verifier) 가 이 과정을 담당하며 만약 검증이 실패한다면 java.lang.VerifyError 를 발생시킨다.

다만, Bootstrap ClassLoader 에 의해 로드된 클래스들은 신뢰성이 높은 자원에서 로드된 클래스이기 때문에 해당 Verification 단계를 거치지 않는다.

 

이러한 Verification 은 사실 컴파일 단계에서도 수행이 된다. 하지만 JVM 에서 다시 한 번 이 검증을 거치게 되면서 클래스 파일의 악의적인 혹은 유효하지 않은 변경을 미연에 방지할 수 있게 된다.

 

 

2-2. 준비(Preparation)

이 단계에서는 static fields 에 대한 메모리를 할당한다. 다만, 주어진 값으로 초기화는 나중에 진행될 Initialize 단계에서 실행되며 이 단계에서는 타입의 기본값으로 초기화가 진행된다. 때문에 이 단계에서 클래스 파일의 코드를 작동시키진 않는다.

 

만약, 이 단계에서 할당할 메모리 공간이 부족하다면 OutOfMemoryError 가 발생한다.

 

 

2-3. 해석(Resolutions)

해석은 해당 클래스의 참조된 클래스들을 로드하는 과정이다.

이 과정은 Linking 의 Preparation 단계에서 수행될 수도 있고, Initialization 단계 이후 수행될 수도 있다.

 

더보기

사실 .class 파일은 실행 시 Link 할 수 있도록 Symbolic Reference 을 가지고 있다. 이 Symbolic Reference 해석 단계에서 Method Area 의 Runtime Constant Pool 을 거쳐 실제로 존재하는 물리적인 주소로 대체되는데, 이러한 Link 작업은 필요할 때마다 동적으로 이루어지기 때문에 Dynamic Linking 이라는 표현을 사용한다.

 

이 Dynamic Linking 이라는 기술 덕분에 class 파일의 크기를 작게 유지할 수 있어 메모리 요구사항이 훨씬 적어지게 되었다.

 

 

Step 3 - 초기화(Initialization)

이 과정에서 로드된 각 클래스나 인터페이스의 코드를 읽고 초기화 로직이 실행되게 된다.

static 변수와 메서드가 코드에 명시된 원래 값으로 할당이 되고, 정적 초기화 블록이 실행되게 된다.

이 작업은 클래스의 위에서 아래로, 클래스 계층 구조에서 부모부터 자식까지 한 줄씩 진행된다.

 

초기화 과정까지 거쳐 클래스 탑재 과정이 끝나게 된다면 본격적으로 JVM 에서 클래스 파일을 구동시킬 준비가 끝나게 된다.

 

 

 

 

 

저작자표시 (새창열림)

'자바' 카테고리의 다른 글

[JAVA] @Retention 어노테이션 알아보기  (0) 2024.03.25
[JAVA] Supplier Interface  (0) 2024.03.25
리플렉션(Reflection)  (0) 2023.07.11
[JVM] 실행 엔진 알아보기 - (3) / 인터프리터, JIT Compiler, GC  (0) 2023.05.17
[JVM] 런타임 영역 알아보기 -(2)  (0) 2023.05.16
  1. JVM 내부구조
  2. Class Loader
  3. Step 1 - 로딩(Loading)
  4. Step 2 - 링킹(Linking)
  5. Step 3 - 초기화(Initialization)
'자바' 카테고리의 다른 글
  • [JAVA] Supplier Interface
  • 리플렉션(Reflection)
  • [JVM] 실행 엔진 알아보기 - (3) / 인터프리터, JIT Compiler, GC
  • [JVM] 런타임 영역 알아보기 -(2)
누누01
누누01
개발이 좋아
누누01
codeCom
누누01
전체
오늘
어제
  • 분류 전체보기 (60)
    • 자바 (6)
    • 스프링 (2)
    • 알고리즘 (0)
    • 자료구조 (0)
    • 백준 (44)
      • 재귀 (6)
      • 브루트포스 (11)
      • 정렬 (12)
      • 백트래킹 (8)
      • DFS&BFS (7)
      • DP (0)
    • leetcode (7)
    • Tool (1)
      • Intellij (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Remove Duplicated from Sorted Array
  • Merge Sorted Array
  • BOJ
  • jvm
  • Spring Security
  • 브루트포스
  • Java
  • 자료구조
  • 알고리즘
  • 자바
  • 정렬
  • 재귀
  • BFS
  • Majority Element
  • Rotate Array
  • Leetcode
  • 백트래킹
  • dfs
  • Supplier Interface
  • Spring

최근 댓글

최근 글

hELLO · Designed By 정상우.
누누01
[JVM] Class Loader 알아보기 - (1)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.