클래스 로더

정민영·2022년 4월 12일

java

목록 보기
3/3

  • 클래스 로더는 '로딩', '링크','초기화' 순으로 진행된다
  • 로딩:
    • 클래스 로더가 .class 파일을 읽고 그 내용에 따라 적절한 바이너리 데이터를 만들고 "메소드"영역에 저장한다.
    • 이때 저장하는 데이터는
      • FQCN : 클래스의 풀 패키지경로, 클래스명, 해당 클래스를 읽고 있는 클래스 로더 정보
      • 클래스인지, 인터페이스인지, 이넘인지에 대한 정보
      • 메서드와 변수
    • 로딩이 끝나면 해당 클래스 타입의 Class 객체를 생성해 '힙'영역에 저장한다.
  • 클래스 로더는 계층 구조로 이루어져 있고 기본적으로 세가지 클래스 로더가 제공된다.
    • 부트스트립 클래스 로더 : JAVA_HOME\lib에 있는 코어 자바 API를 제공한다. 최상위 우선순위를 가진 클래스 로더다.
    • 플랫폼 클래스로더: JAVA_HOME\lib\ext또는 java.ext.dirs 시스템 변수에 해당하는 위치에 있는 클래스를 읽는다.
    • 애플리케이션 클래스로더 : 어플리케이션 클래스패스(어플리케이션 실행할때 -calsspath옵션 또는 java.class.path 환경 변수의 값에 해당하는 위치이다.)에서 클래스를 읽는다.
System.out.println("hello!! class loader!");
ClassLoader classLoader = App.class.getClassLoader();
System.out.println(classLoader);
System.out.println(classLoader.getParent());
System.out.println(classLoader.getParent().getParent());
-> 출력
hello!! class loader!
jdk.internal.loader.ClassLoaders$AppClassLoader@512ddf17
jdk.internal.loader.ClassLoaders$PlatformClassLoader@7dc36524
null
  • 위의 코드를 보면 알수 있듯이 모든 클래스는 클래스로더를 통해 메모리에 올라가고 클래스로더는 3가지로 분류되 가장 위의 부트스트랩부터 클래스를 읽어 오는데 boot가 못읽으면 plat이, plat이 못읽으면 appli가, appli가 못읽으면 ClassNotFoundException이 발생한다. 각자 맡은 위치의 클래스를 메모리에 올리는 역할을 한다고 파악할 수 있다.

  • 링크 : 로딩 다음에 링크라는 과정이 있는데 링크는 verify, Prepare, Resolve 세단계로 나눠져 있다.

    • verify(검증): .class 파일형식이 유효한지 체크한다고 한다. 만약 .class파일이 변경되거나 이해할수 없는 파일이 되면 안되기 때문에 검증의 과정이 필요하다.
    • Prepare: 클래스 변수(static변수)와 기본값에 필요한 메모리를 준비한다.
    • Resolve: 심볼릭 메모리 레퍼런스를 메서드 영역에 있는 실제 레퍼런스로 교체한다. 이말은 만약 App app = new App();이라고 선언되있어도 링크 과정에서는 실제 레퍼런스를 가리키고 있지 않고 일종의 논리적은 레퍼런스를 가지고 있고하고 이것을 '심볼릭 메모리 레퍼런스'라고 표현했다. 이 심볼릭 레퍼런스를 실제 힙영역의 레퍼런스 값으로 바꿔준다. 다만 이 과정은 옵션이라 설정에 따라 링크의 Resolve에서 처리할지 아닐지 정할 수 있다.
  • 초기화 : 어플리케이션의 static이 붙은 항목들은 모두 클래스로더의 초기화 시점에 할당된다.

0개의 댓글