JVM 클래스 로더

박종현·2022년 5월 15일

자바(Java) 기본

목록 보기
3/8

JVM 클래스 로더

JVM 클래스 로더란?

컴파일러를 통해 .class 확장자를 가진 클래스 파일은 여러 디렉터리에 흩어져 있고 기본적인 라이브러리의 클래스 파일들은 $JAVAHOME_ 내부 경로에 위치하는데 각각의 클래스 파일들을 찾아서 런타임 시점에 동적으로 JVM의 메모리에 탑재해주는 역할을 하는것이 JVM의 클래스 로더이다.

  • 클래스 로더는 런타임 중에 JVM의 메소드 영역에 동적으로 Java 클래스를 로드한다
  • 클래스 로더 동작 과정은 로딩(Loading), 링크(Linking), 초기화(Initialization) 단계로 나뉘어져 있다.

클래스 로더 계층

  1. Bootstrap ClassLoader

    • 최상위 계층의 ClassLoader, 즉 모든 클래스로더의 부모가 되는 클래스 로더
    • rt.jar 를 포함하여, JVM을 구동시키기 위한 가장 필수적인 라이브러리의 클래스들을 JVM에 탑재
    • 탑재되는 운영체제에 맞게 네이티브 코드로 작성됨
    • $JAVAHOME/jre/lib/ext_ 에 위치
  2. Extensions ClassLoader

    • BootStrap ClassLoader다음으로 우선순위를 가지는 클래스 로더
    • 표준 핵심 Java Class 의 라이브러리들을 JVM 에 탑재하는 역할
  3. Application(System) ClassLoader

    • ClassPath에 있는 클래스들(개발자들이 자바코드로 작성한 클래스 파일)을 탑재
  4. 각 계층의 클래스 로더의 구현 구조

    static class ExtClassLoader extends URLClassLoader {
    }
    
    static class AppClassLoader extends URLClassLoader {
    }
    
    public class URLClassLoader extends SecureClassLoader implements Closeable{
    }
    
    public class SecureClassLoader extends ClassLoader {
    }
    
    public abstract class ClassLoader{
    }

클래스 로더의 동작 방식

클래스 로더는 새로운 클래스를 로드해야 할 때, 다음과 같은 방식으로 로드를 수행한다.

  1. JVM의 메소드 영역에 클래스가 로드되어 있는지 확인한다. 만일 로드되어 있는 경우 해당 클래스를 사용
  2. 메소드 영역에 클래스가 로드되어 있지 않을 경우, 시스템 클래스 로더에 클래스 로드를 요청
  3. 시스템 클래스 로더는 확장 클래스 로더에 요청을 위임
  4. 확장 클래스 로더는 부트스트랩 클래스 로더에 요청을 위임
  5. 부트스트랩 클래스 로더는 부트스트랩 Classpath(JDK/JRE/LIB)에 해당 클래스가 있는지 확인한다. 클래스가 존재하지 않는 경우 확장 클래스 로더에게 요청을 넘긴다
  6. 확장 클래스 로더는 확장 Classpath(JDK/JRE/LIB/EXT)에 해당 클래스가 있는지 확인한다. 클래스가 존재하지 않을 경우 시스템 클래스 로더에게 요청을 넘긴다
  7. 시스템 클래스 로더는 시스템 Classpath에 해당 클래스가 있는지 확인한다. 클래스가 존재하지 않는 경우 ClassNotFoundException을 발생시킨다.

클래스 로더 동작 과정

  1. Loading

    • 클래스로더의 하위 계층으로 요청이 상위 계층으로 위임되고 클래스 존재 유무에 따라 다시 하위 계층으로 요청을 넘긴다.
    • 하위 클래스 로더가 로드한 클래스 파일은 상위 클래스 로더가 로드한 클래스 파일을 볼 수 있음(Visibility)
    • JVM에 탑재된 클래스 파일은 종료될 때 까지 JVM에서 제거되지 않는다.
  2. Linking

    Linking 은 로드된 클래스 파일들을 검증하고, 사용할 수 있게 준비하는 과정을 의미

    1. Verification : 클래스 파일이 유효한지를 확인하는 과정
    2. Preparation : 클래스 및 인터페이스 static filed 메모리 할당 및 기본값으로 초기화
    3. Resolution : 심볼릭 메모리 레퍼런스를 메소드 영역에 있는 실제 레퍼런스로 교체한다.
  3. Initialization

    • 클래스 파일의 코드를 읽고 static 필드의 값을 초기화, 초기화 매서드를 실행시킨다
    • 멀티쓰레딩으로 동작하기 때문에 초기화 단계에서 동시성 문제를 고려해야한다

클래스 로더가 지켜야 할 세 가지 원칙

  • 위임 원칙 클래스 로더는 클래스 또는 리소스를 찾기 위해 요청을 받았을 때, 상위 클래스 로더에게 책임을 위임하는 위임 모델을 따른다.
  • 가시 범위 원칙 하위 클래스 로더는 상위 클래스 로더가 로드한 클래스를 볼 수 있지만, 반대로 상위 클래스 로더는 하위 클래스 로더가 로드한 클래스를 알 수 없다.
  • 유일성의 원칙
    • 하위 클래스 로더가 상위 클래스 로더에게 로드한 클래스를 다시 로드하지 않아야 한다는 원칙이다.
    • 위임 원칙에 의해서 위쪽으로 책임을 위임하기 때문에 고유한 클래스를 보장할 수 있다.

클래스 로딩 & 초기화시점

  • 클래스 로딩 시점
    • 클래스의 인스턴스 생성
    • 클래스의 정적 변수 사용 (final 키워드 X)
    • 클래스의 정적 메소드 호출
  • 클래스가 로딩 X
    • 클래스에 접근하지 않을 때
    • 클래스의 정적 변수 사용 (final 키워드 O)
  • 초기화 시점
    • 클래스의 인스턴스 생성
    • 클래스의 정적 변수 사용 (final 키워드 X)
    • 클래스의 정적 메소드 호출

0개의 댓글