본문 바로가기

공부방/JAVA

클래스로더 시스템

클래스 로더 시스템 구조를 조금 더 자세하게 그리면 아래와 같이 그릴 수 있다.

여러개의 클래스 로더들이 (Bootstrap, Extension, Application) 부모 - 자식 간의 관계를 맺고 로딩을 한다. 

 

링크라는 과정도 세부적으로 세단계로 나눠서 실행이 된다.

 

클래스 로더


로딩, 링크, 초기화 순으로 진행된다.

 

로딩

 

  • 클래스 로더가 .class 파일을 읽고 그 내용에 따라 적절한 바이너리 데이터를 만들고 “메소드” 영역에 저장.
  • 이때 메소드 영역에 저장하는 데이터
    • FQCN (Fully qualified class name, 패키지 경로를 포함한 클래스 이름)
    • 클래스 | 인터페이스 | 이늄
    • 메소드와 변수
    • 로딩이 끝나면 해당 클래스 타입의 Class 객체를 생성하여 “힙" 영역에 저장.

플랫폼 클래스로더 위에 있는 부트스트랩 클래스로더가 네이티브로 구현되어 있는 클래스 로더라서 vm마다 다르고

자바에서 참조해서 출력할 수가 없다.

 

우리가 구현한 클래스는 대부분 애플리케이션 클래스로더가 읽게 된다.

클래스로더가 동작하는 원리는

부모가 제일 먼저 읽어오고, 부모가 못읽으면 그다음 부모가 읽고 그다음 부모도 못 읽으면 본인이 읽는다 (어플리케이션 클래스로더) 본인도 못읽을 경우 classnotfoundException이 발생한다. 

 

링크

 

Verify, Prepare, Reolve(optional) 세 단계로 나눠져 있다.

  • verify (검증) : .class 파일 형식이 유효한지 체크한다. (임의로 컴파일된 클래스 파일을 조작하면 에러 나고 종료)
  • Preparation (준비) : 클래스 변수(static 변수)와 기본값에 필요한 메모리를 준비하는 과정
  • Resolve: 심볼릭 메모리 레퍼런스를 메소드 영역에 있는 실제 레퍼런스로 교체한다.(optional, 이때 발생할 수도 있고 실제 사용될 때 발생할 수도 있음)

Resolve의 예)

아래 코드에서 Book은 실제 Book 레퍼런스를 가리키고 있는 것은 아닌 논리적인 레퍼런스이다.

Heap에 있는 객체를 가리키도록 하는 과정이 Resolve 과정에서 진행될 수도 있고 아닐 수도 있다. (Optional이기 때문)

 

초기화

 

링크 - preparation에서 준비해놓은 메모리에다가 static한 변수의 값을 할당하는 과정.

Static 변수의 값을 할당한다. (static 블럭이 있다면 이때 실행된다.)

 

클래스 로더는 계층 구조로 이뤄져 있으면 기본적으로 세가지 클래스 로더가 제공된다.

  • 부트 스트랩 클래스 로더 -  JAVA_HOME\lib에 있는 코어 자바 API를 제공한다. 최상위 우선순위를 가진 클래스 로더
  • 플랫폼 클래스로더 (익스텐션 클래스로더) - JAVA_HOME\lib\ext 폴더 또는 java.ext.dirs 시스템 변수에 해당하는 위치에 있는 클래스를 읽는다. 
  • 애플리케이션 클래스로더 - 애플리케이션 클래스패스(애플리케이션 실행할 때 주는 -classpath 옵션 또는 java.class.path 환경 변수의 값에 해당하는 위치)에서 클래스를 읽는다.