Java

클래스 로더

박성민 2021. 10. 26. 21:57

2

클래스 로더

  • 로딩, 링크, 초기화 순으로 진행됩니다.
  • 로딩
    • 클래스 로더가 .class 파일을 읽고 그 내용에 따라 적절한 바이너리 데이터를 만들고 "메소드" 영역에 저장.
    • 이때 메소드 영역에 저장하는 데이터
    • FQCN
      • 풀 패키지 경로를 포함한 클래스 이름
    • 클래스 | 인터페이스 | 이늄
    • 메소드와 변수
    • 로딩이 끝나면 해당 클래스 타입의 Class 객체를 생성하여 "힙" 영역에 저장.
  • 링크
    • Verify, Prepare, Resolve(optional) 세 단계로 나눠져 있습니다.
    • 검증: .class 파일 형식이 유효한지 체크합니다.
    • Preparation: 클래스 변수(static 변수)와 기본값에 필요한 메모리를 준비하는 과정
    • Resolve: 심볼릭 메모리 레퍼런스를 메소드 영역에 있는 실제 레퍼런스로 교체합니다.
      • 심볼릭 메모리 레퍼런스: 다른 객체를 참조하고 있는 레퍼런스
      • Resolve가 이 과정에서 발생할수도 있고 하지 않을 수도 있습니다.(Optional)
  • 초기화
    • Static 변수의 값을 할당합니다. (static 블럭이 있다면 이때 실행됩니다.)
      • 링크의 Preparation 과정에서 준비된 static 변수들의 값을 할당합니다.
  • 클래스 로더는 계층 구조로 이뤄져 있으며 기본적으로 세 가지 클래스 로더가 제공됩니다.
    • 부트 스트랩 클래스 로더 - JAVA_HOME\lib에 있는 코어 자바 API를 제공합니다. 최상위 우선순위를 가진 클래스 로더
    • 플랫폼 클래스로더 - JAVA_HOME\lib\ext 폴더 또는 java.ext.dirs 시스템 변수에 해당하는 위치에 있는 클래스를 읽습니다.
      • 예전에는 익스텐션 클래스로더라고 불렀었음.
    • 애플리케이션 클래스로더 - 애플리케이션 클래스패스(애플리케이션 실행할 때 주는 -classpath 옵션 또는 java.class.path 환경 변수의 값에 해당하는 위치)에서 클래스를 읽습니다.
      • 우리가 만든 클래스 또는 스프링 관련 클래스들은 애플리케이션 클래스로더가 읽습니다.
      • 최상위 부모가 먼저 읽고, 그다음 부모, 부모 모두 못읽을 경우 본인이 읽습니다.
      • 본인도 못읽는 경우에는 ClassNotFoundException이 발생합니다.
public class Smpaaark {

    public void work() {
        Class<Smpaaark> smpaaarkClass = Smpaaark.class;
        Smpaaark smpaaark = new Smpaaark();
        smpaaark.getClass();
    }
}

(Class 객체)

  • 클래스명.class 또는 인스턴스 생성 후 .getClass()로 가져올 수 있는 객체입니다.
public class App {

    Book book = new Book();

    ...
}

(심볼릭 메모리 레퍼런스)

public class App {

    static String name = "seongmin";

    static {
        name = "seongmin";
    }

    ...
}

(static 변수들)

public class App {

    public static void main( String[] args ) {
        ClassLoader classLoader = App.class.getClassLoader();
        System.out.println(classLoader);
        System.out.println(classLoader.getParent());
        System.out.println(classLoader.getParent().getParent());
    }
}

1
(클래스로더 확인)

  • App의 클래스로더는 애플리케이션 클래스로더
  • 애플리케이션 클래스로더의 부모는 플랫폼 클래스로더
  • 플랫폼 클래스로더의 부모도 있는데 네이티브 코드로 구현되어있는 클래스로더라서 자바 코드로 출력이 불가합니다.

참조