학습일지/Language

JVM의 ClassLoader 정리

inspirit941 2020. 10. 16. 18:39
반응형

JVM 구조

jvm-3

JVM은 다섯 가지 컴포넌트로 구성되어 있다.

  • 클래스 로더 시스템 : 컴파일 결과로 만들어진 .class 바이트코드 파일을 읽어들여 메모리에 배치.
    • 로딩, 링크, 초기화 세 가지 과정을 거친다.
  • 메모리
  • Runtime Engine: 바이트코드를 읽어들이는 인터프리터가 작동하는 영역.
    • 바이트 코드를 기계어로 변환하면서 Line by Line 실행하는 방식.
    • 여기 인터프리터가 기계어 코드를 실행할 때, 한 번 변환한 바이트코드를 또 변환하는 대신

      실행한 코드를 저장하는 영역이 있다. 그게 Code Cache (JIT Compiler라고도 부른다). 프로그램 실행속도를 향상시키는 용도.
    • Garbage collection.
  • Native Method interface
  • Native Method library

참고자료


ClassLoader

Java-Class-Loader_1

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

  • 로딩: 클래스를 읽어오는 과정
  • 링크: 레퍼런스 연결 과정
  • 초기화 : static 값 초기화하고 변수 할당하는 과정

로딩

  1. 클래스 로더가 .class 파일을 읽고, 내용에 맞는 binary 데이터를 생성한 뒤 메모리의 Method 영역에 저장한다. (MetaSpace)

    • FQCN (Fully Qualified Class Name). 클래스가 속한 패키지명을 모두 포함한 이름
    • 클래스, 인터페이스, Enum
    • 각 클래스 / 인터페이스의 메소드, 변수
  2. 로딩이 끝나면, 해당 클래스 타입의 class 객체를 생성해서 Heap 영역에 저장한다.

    • 객체이름.class 또는 인스턴스의 getClass() 형태로 호출했을 때 리턴되는 값을 말함.
    • Class<객체이름> 형태.

클래스 로더의 종류는 세 가지.

classloader-in-java3

  • 부트스트랩 클래스 로더 (플랫폼의 부모 클래스)
  • 플랫폼 클래스 로더 (애플리케이션의 부모 클래스)
  • 애플리케이션 클래스 로더 (System Class Loader라고도 부른다)

부트스트랩과 플랫폼 클래스 로더는 jre (자바런타임)에 있는 jar 파일을 읽는 용도.

자바의 기본 내장클래스를 활용할 용도로 사용함.

AppClassLoader는 개발자가 생성해서 classpath에 컴파일된 클래스 파일을 읽는 용도.

public class App {
    public static void main(String[] args) {
        ClassLoader classLoader = App.class.getClassLoader();
        classLoader; 
        // AppClassLoader 리턴
        classLoader.getParent(); 
        // PlatformClassLoader 리턴
        classLoader.getParent().getParent(); 
        // null 리턴. 부트스트랩 클래스로더는 native로 구현되어 있어 자바에서 확인이 불가능하다.
    }
}

가장 부모 클래스로더부터 필요한 클래스를 읽어들이는데,
AppClassLoader 에서도 읽어들이지 못하면 ClassNotFoundException이 발생한다.

링크

세 단계로 나뉘어진다.

  • Verfiy : .class 형식 파일이 유효한지 확인. 바이트코드가 조작될 경우 JVM 에러 발생.
  • Prepare : 메모리 준비 과정. 클래스의 static변수, 기본값에 필요한 메모리를 준비
  • Resolve : Symbolic Memory Reference 를 실제 Reference로 교체 (Optional 과정)

가령 Book book = new Book(); 이라는 코드가 있다고 할 때,
book이라는 참조변수가 Heap에 저장된 실제 Book 클래스를 가리킬 수 있도록 연결하는 게 Resolve 과정이다.

초기화

static으로 선언된 변수와 메소드에 메모리를 할당, 초기값을 채우는 과정.
static final String name = "staticName"; 코드가 클래스에 있다면, 여기서 초기화된다.

 


ClassLoader를 알아야 하는 이유?

WAS에 내가 만든 웹앱이 올라가는 경우가 있다. Tomcat에 war 파일 형태로 서비스를 제공할 경우라던가.

  • 이 경우 메인 메소드는 웹앱 서버 (WAS)가 통제하고, 내 애플리케이션이 메인 메소드 내에서 실행되는 구조.

배포한 뒤, 코드를 수정해서 재배포해야 하는 경우가 생겼다고 가정하자.

클래스로더로 클래스를 메모리에 올리고 나면, 클래스 정보를 지우는 방법이 따로 없다. 프로그램을 종료하는 방법 외에는.

클래스를 변경했을 때, 변경된 클래스가 적용되도록 하려면?

  • User Defined Class Loader가 필요하다. ex) Tomcat ClassLoader 구조

특히 상위 클래스로더에서 읽어들인 클래스일수록, 나중에 클래스를 변경하기 어렵다.

 

 

 

참고자료

반응형