Skip to content

김수현, 김현준, 윤중진, 홍은기 JVM

kariskan edited this page Jul 10, 2024 · 8 revisions

Class Loader

  • 컴파일러를 통해 .class 확장자를 가진 클래스 파일들은 각각의 디렉토리에 존재한다. 기본 라이브러리의 클래스 파일들도 $JAVAHOME 내부의 경로에 존재한다. 이렇게 흩어진 클래스 파일들을 찾아서 Dynamic Loading 방식으로 Runtime Data Area에 올리는 것이 클래스 로더의 역할이다.
  • Loading
    • 컴파일된 클래스 파일을 메모리에 로딩하는 과정이다. 로딩할때 클래스 로더는 3가지의 구현체가 동작하는데, Bootstrap, Extension, Application class loader가 순서대로 동작하게 된다.
      • 그래서 개발자가 직접 클래스로더를 정의해서 로딩 과정에 집어 넣을수도 있고, 이걸 User-Defined Class Loader라 부른다.
      • Bootstrap Class Loader는 lang.Object lang.Class util.* 이런 자바에 필수적인 클래스들을 올리게 된다.
      • Application Class Loader는 개발자가 만든 .class 파일을 로드한다.
        • 즉, class path의 클래스들을 전부 로드한다.
        • 외부 라이브러리 클래스들도 로딩하는지는 모르겠다.
      • 결론은 Bootstrap → extension → application 순으로 자기 역할에 맞는 클래스를 찾게 되고 존재하지 않으면 ClassNotFoundException을 발생시킨다.
    • 자바는 동적 로딩 방식을 사용하는데, 존재하는 모든 .class 파일을 메모리(메서드 영역)에 올리는게 아니라, 필요할 때 올린다는 것이다 → dynamic loading
    • 그래서 클래스가 로딩되면 메서드 영역에 클래스 정보(클래스 바이트 코드 파일)를 저장한다. 그래서 이 메서드 영역의 클래스 정보를 보고 리플렉션이 클래스에 대한 정보를 알 수 있는 것이다.
  • Linking
    • 로딩된 클래스 파일을 검증하고 사용할 수 있게 준비하는 과정이다. Verification, Preparation, Resolution 세 단계로 이루어져 있다.
    • Verificatoin
      • Java의 규칙대로 클래스를 잘 작성했는지 확인한다. 구조에 잘 맞춰서 작성했는지 등을 검사하는 것으로 뭔가 문제가 발생한다면 VerifyException이 발생한다.
      • Bytecode Verifier가 처리를 담당함. 예를 들면 final 메서드, 클래스가 override 됐는가 이런 걸 검사함
    • Preparation
      • 클래스나 인터페이스에 대한 정적 필드를 생성하고 해당 필드를 기본값으로 초기화하는 작업을 한다. 실제 할당된 값이 아닌, int의 경우 0, String의 경우 null과 같이 초기화한다. 실제 값은 이후 initialization 과정에서 바인딩되기 때문에 초기화 블록이나 코드가 실행되지 않는다.
    • Resolution
      • runtime constant pool에 있는 symbolic reference(심볼릭 참조)를 direct reference(직접 참조)로 변경한다.
      • symbolic reference는 코드를 작성하면서 사용한 class, field, method의 이름을 지칭한다. 즉, 정확한 주소 값이 아니다. 이를 정확한 주소 값인 direct reference로 변경하는 것이다.
        • 우선 클래스를 로드하면서 constant pool에 클래스 이름으로 임의의 reference인 symbolic reference를 사용하고(예를 들면 MyClass$myVariable) 이런 식으로? linking과정에서 검증 후, 검증이 완료되었으니 실제 메모리 주소로 매핑해주는 것으로 이해했다.
  • Initialization
    • 클래스의 생성자를 호출하여 초기화를 진행한다.
    • 실제 클래스 파일의 코드를 읽는 것으로, 자바 코드에서의 클래스와 인터페이스의 값들을 지정한 값들로 초기화 및 초기화 메소드를 실행시키는 과정이다. 이때 JVM은 멀티 스레드로 동작하여 같은 시간에 한 번에 초기화를 하는 경우가 있기 때문에 멀티스레드 환경을 고려하지 않을 경우 클래스 초기화 과정 중 오류가 발생할 수 있다.
      • 생성자(또는 초기화 블록 같은 곳)에 멀티스레드 관련된 동기화가 요구되는 코드를 넣지 말라는 뜻이다.
    • 여기서 생성자 호출은 실제로 new 키워드로 생성한 것이 아닌, 로딩을 마친 이후에 힙 영역에 해당 클래스 타입의 객체를 따로 생성한다.
      • 이건 JVM의 필요에 의해 클래스의 인스턴스를 만들어 놓는 것이다.
      • 예시로는 코드를 작성할 때 내가 만든 클래스에 접근할 수 있는 것이 JVM이 객체를 생성했기 때문이다. ClassName.class.getClass() 와 같이 new로 생성하지 않아도 해당 클래스 정보에 접근이 가능한 것이 JVM이 객체를 하나 생성했기 때문으로 이해함

👼 개인 활동을 기록합시다.

개인 활동 페이지

🧑‍🧑‍🧒‍🧒 그룹 활동을 기록합시다.

그룹 활동 페이지

🎤 미니 세미나

미니 세미나

🤔 기술 블로그 활동

기술 블로그 활동

📚 도서를 추천해주세요

추천 도서 목록

🎸 기타

기타 유용한 학습 링크

Clone this wiki locally