jvm의 동작원리

자바 공부를 하면서 참고한 서적입니다.

명품자바에센셜(생능출판사, 황기태), 이것이 자바다(한빛미디어, 신용권)

JVM의 동작원리

JDK(Java Development Kit)의 구조는 다음과 같이 생겼습니다.

jdk

JVM(Java Virtual Machine)은 플랫폼 종속적입니다. JVM이 있기에 자바가 플랫폼 독립적이 될 수 있습니다.

JVM은 다음과 같이 동작하며 다음과 같은 구성요소를 가지고 있습니다.

jvm

크게 3가지로 분류하면 클래스 파일과 라이브러리를 로딩하는 Class Loader SubSystem 로딩된 데이터를
실행하기 위한 Runtime data Area 그리고 이 클래스를 실행하는 Execution Engine으로 구성됩니다.

Runtime data Area를 메모리 공간이라고 하며 총 5개로 나누어 관리하고 크게 3가지로 분류됩니다.

위 링크에서 JVM의 메모리 구조에 대해 배웠으므로 이번에는 나머지 두 개에 대해서 배워 보겠습니다.

  • Class File

개발자가 만드는 혹은 이미 만들어진 프로그램을 말하며 확장자가 .java입니다.
.java에서 컴파일 과정을 거치면 .class가 생기며 이 클래스 파일은 JVM에서 실행 가능한 파일입니다.
이클립스에서 생성한 Package는 Directory이며 Package의 src디렉터리 안에 .java 파일이 있으며
Package의 bin디렉터리 안에 .class파일이 있습니다.

  • Class Loader SubSystem

    Class Loader SubSystem의 Class Loader란 자바의 큰 장점 중 하나로 컴파일시가 아닌 런타임시
    클래스를 로딩할수 있게 해주는 기술입니다.

    JVM의 클래스 로더 서브시스템의 동작 원리는 다음과 같습니다.

    loading - linking - initialization

    roader

    클래스 로더의 구조는 BootStrap-Extension-Application의 구조를 가지고 있습니다.

    loader

    • BootStrap class loader

      VM의 일부로 구현되고 클래스 로더와 달리 자바 코드로 인스턴스화가 불가능합니다.

    • Extension class loader

      BootStrap의 하위 클래스 로더이며 $JAVA_HOME/jre/lib/ext에 위치한 JAR파일이 그 대상이 됩니다.

    • Application class loader

      $CLASSPATH에 지정된 경로에서 class를 로딩합니다.

    • Dynamic Loading(동적로딩)

      프로그램을 실행하는 도중에 새로운 클래스를 로딩할 수 있습니다.

      1. Load time dynamic loading : 프로그램 실행 초기에 클래스를 로딩
      2. Runtime dynamic loading : 프로그램 실행 중간에도 클래스를 로딩
      public class HelloWorld {
        public static void main(String[] args) {
          System.out.println("Hello World");
        }
      }
      

      위 파일을 실행하기 위해서는 다음과 같이 입력할 것입니다.

      $ java HelloWorld

      이 경우에 JVM이 시작되고, 부트스트랩 클래스 로더가 생성된 후에 최상위 클래스인 Object클래스를
      읽어옵니다. 그 후에 클래스 로더는 HelloWorld 클래스를 로딩하기 위해 HelloWorld.class 파일을
      읽을 것이며 HelloWorld 파일을 로딩하는 과정에서 필요한 클래스가 있는데 바로 java.lang.String과 java.lang.System입니다.
      이 두 클래스는 HelloWorld 클래스를 읽어오는 과정 즉, Load time에 로딩됩니다.
      이 처럼 하나의 클래스를 로딩하는 과정에서 동적으로 클래스를 로딩하는 것을 Load time dynamic loading이라고 합니다.

      Runtime dynamic loading은 다음과 같습니다.

      public class RuntimeDynamicLoading {
        public static void main(String[] args) {
          Class klass = Class.forName(args[0]);
          Object obj = klass.newInstance();
        }
      }
      

      RuntimeDynamicLoading의 main()메소드가 실행되고 Class.forName(args[0])를 호출하는 순간에
      그때서야 args[0]에 해당하는 클래스를 읽어옵니다. 이 처럼 로딩할 때가 아니라 코드를 실행 하는 순간
      로딩하는 것을 Runtime dynamic loading이라고 합니다.

Reference : HOONEST