Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save taekwon-dev/95ed5734164fa449082601cff8733c14 to your computer and use it in GitHub Desktop.
Save taekwon-dev/95ed5734164fa449082601cff8733c14 to your computer and use it in GitHub Desktop.

[Java] How is a Java Program executed [2-1] JVM 구성 요소 - Class Loader

지난 글에서는 JVM 과 실행 및 개발 환경과 관련해 JRE, JDK 을 순서대로 알아봤다.

image

[ 그림 1 ]

이번 글에서는 JVM 의 구성 요소 세 가지 중 하나인 클래스 로더를 다룰 예정이다. 참고로 JVM 은 [ 그림 1 ] 에서 볼 수 있듯이 클래스 로더 시스템 + 런타임 메모리 영역 + 실행 엔진으로 구성되어 있다.


| 클래스 로더

image

[ 그림 2 ]

자바 컴파일러를 통해 자바 소스 코드가 컴파일 되어.class 확장자를 가지는 바이트 코드가 생성된다. 바이트 코드는 여러 디렉터리에 나뉘어 흩어져 있는데, 클래스 로더가 각각의 클래스를 JVM 메모리 에 로드하는 역할을 한다.

자바는 동적 로드 특징을 가지고 있다. 여기서 동적 로드란 컴파일 시점에 모든 클래스를 메모리에 로드하지 않는다는 것을 의미한다. 클래스 로더는 동적 로드를 수행하는 역할을 가진다고 볼 수 있고, 클래스 로더가 클래스를 로드 하는 과정은 크게 로딩 -> 링크 -> 초기화 단계로 나뉘어 있다.

image

[ 그림 3 ]

(원문) They’re also part of the JRE (Java Runtime Environment). Therefore, the JVM doesn’t need to know the underlying files or file systems in order to run Java Program thanks to class loaders.

(번역) 참고로 클래스 로더는 JRE 의 구성 요소이고, 따라서 JVM 은 자바 프로그램 구동을 위해 필요한 클래스 파일에 대해 모두 알 필요가 없다.

image

[ 그림 4 ]

위 인용문의 내용은 JRE 가 실행 환경을 제공한다는 것의 의미를 보다 강력히 느낄 수 있게 해준다. 클래스 로더는 JVM 이 바이트 코드를 기계어로 번역할 수 있도록 바이트 코드를 JVM 의 메모리 영역에 로드하는 역할을 해준다. 따라서 위 인용 내용과 같이 JVM 는 직접 모든 클래스 파일을 알 필요 없고, 클래스 로더 시스템을 활용하면 된다.


| 클래스 로딩 과정 (로딩 ► 링크 ► 초기화)

클래스 로딩 과정은 위 소제목에서 알 수 있듯이 로딩, 링크, 초기화 순서대로 진행된다.

image

[ 그림 5 ]

로딩

로딩 과정을 통해 .class 내 바이트 코드를 기반으로 바이너리 코드 를 만들어 메모리의 메서드(Method) 영역에 저장하고, 이때 메서드 영역에 저장하는 목록은 아래에서 확인할 수 있다.

  • FQCN (Full-Qualified Class Name)
  • Type 정보 (Interface, Class 또는 Enum)
  • 변수, 메서드 정보

또한 로딩 이후 해당 클래스 타입의 Class 객체를 생성해서 JVM 메모리의 힙(Heap) 영역에 저장한다.

[ 그림 5 ] 와 같이 로딩 과정은 어떤 대상을 로딩할 것인지에 대한 기준에 따라 크게 Bootstrap , Platform , Application 클래스 로더로 구분되고, 계층 구조를 가진다. 각 클래스 로더에 대한 내용은 하단에서 보다 자세히 다룰 예정이다.

링크

링크 과정은 Verify, Preparation, Resolve 단계로 진행된다. 먼저 Verify단계에서는 이름 그대로 .class 파일 형식이 JVM 명세에 맞는지 확인한다. Verify 단계를 통과하면, Preparation 과정에서 해당 파일이 필요한 메모리를 준비하고 마지막 Resolve 단계에서는 심볼릭 메모리 레퍼런스를 메모리의 메서드 영역에 있는 실제 레퍼런스로 교체한다.

링크 과정의 마지막 단계인 Resolve 에서 심볼릭 메모리 레퍼런스가 메모리의 메서드 영역에 있는 실제 레퍼런스로 교체된다는 것의 배경을 잠시 설명하면 아래와 같다.

image

[ 그림 6 ]

[ 그림 6 ] 을 보면, 주소(Address) 의 종류가 세 가지가 등장한다.

  • Symbolic Address
  • Logical Address (= Virtual Address)
  • Physical Address

우리가 소스 코드를 작성할 때 변수 또는 메서드를 선언하고 해당 변수 또는 메서드를 호출해서 사용하는 경우가 있는데, 이 때 사용하는 주소는 Symbolic Address 다. 여기서 핵심은 소스 코드 작성 시 사용하는 변수, 메서드 등이 실제 저장되어 있는 Physical Address 를 참조하는 것이 아니라는 점이다. 하지만 결국 해당 변수가 가리키는 값이 저장되어 있는 메모리 공간을 참조해야 하므로 Symbolic ► Logical ► Physical Address 로 매핑 과정이 필요하다.

앞서 링크 과정의 Resolve 단계에서 심볼릭 메모리 레퍼런스를 메모리의 메서드 영역의 실제 메모리 레퍼런스로 교체한다는 맥락 역시 위 내용을 기반으로 이해할 수 있다. 위 내용은 여기 에서 보다 자세히 확인할 수 있다.

초기화

마지막 단계인 초기화 단계에서는 static 변수가 초기화 된다.


| Reference

Class Loaders in Java | Baeldung Java JVM의 클래스 로더란? 더 자바, 코드를 조작하는 다양한 방법 - 클래스 로더 JVM에 관하여 - Part 2, ClassLoader

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment