HotSpot VM은 어떻게 구성되어 있을까?

HotSpot이란?

  • 자바에서 한 때 성능 개선을 위해 Jut In Time(JIT) 컴파일러를 만들었고, 이름을 HotSpot으로 지었다.
  • HotSpot은 자바 1.3부터 기본 VM으로 사용되어 왔기 때문에, 지금 운영되고 있는 대부분의 시스템들은 모두 HotSpot 기반의 VM이라고 생각하면 된다.
  • HotSpot VM은 세가지 주요 컴포넌트로 되어 있다.
    • VM(Virtual Machine) 런타임
    • JIT(Just In Time) 컴파일러
    • 메모리 관리자
  • HotSpotVM은 GC방식과, JIT 컴파일러가 HotSpot VM 런타임에 레고처럼 끼워 맞춰진다고 볼 수 있다.
  • 이를 위해 VM 런타임은 JIT컴파일러용 API와 가비지 컬렉터용 API를 제공한다.
  • 그 외에도, JVM을 시작하는 런처와 스레드 관리, JNI등도 VM 런타임에서 제공한다.

JIT Optimizer란 무엇인가?

  • 우선 JIT Optimizer에 대해 알아보기 전에, 기초적인 지식에 대해 알아보자.
  • 컴파일 : 상위 레벨의 언어로 만들어진 기계에 의존적인 코드로 변환하는 것
  • 자바는 javac라는 컴파일러를 사용해, 소스코드를 바이트 코드로 된 class파일로 변환한다. 그렇기 때문에 JVM은 항상 바이트 코드로 시작하며, 동적으로 기계에 의존적인 코드로 변환해준다.
  • 초기 JVM 구동시 모든 코드는 인터프리터에 의해 시작되고, 해당 코드가 충분히 많이 사용될 경우 JIT 방식으로 컴파일할 대상이 된다.
    • 각 메서드에 있는 카운터를 통해 통제된다.

JVM의 시작 절차

java 명령으로 HelloWorld라는 클래스를 실행하면 어떤 단계로 수행될까? 정ㄹ해보면 다음과 같다.

  1. java 명령어 줄에 있는 옵션 파싱
  2. 자바 힙 크기 할당 및 JIT 컴파일러 타입 지정
  3. CLASSPATH, LD_LIBRARY_PATH같은 환경 변수 지정
  4. 자바의 Main 클래스가 지정되어 있지 않을 경우 Jar 파일의 manifest 파일에서 Main 클래스 확인
  5. JNI의 표준 API인 JNI_CreateJavaVM을 사용해 새로 생성한 non-primordial이라는 스레드에서 HotSpot VM 생성
  6. HotSpot VM 생성후 초기와 완료시 Main 클래스가 로딩된 런처에서는 main() 메서드의 속성정보를 읽는다.
  7. CallStatisVoidMethod라는 네이티브 인터페이스를 불러 main() 메서드 실행

JVM의 종료 절차

  1. HotSpot VM이 작동중인 상황에서는 단 하나의 데몬이 아닌 스레드(nondaemon thread, OS가 사용하지 않는, 애플리케이션 단에서 수행되는 스레드)가 수행될 때 까지 대기한다.
  2. Shutdown 클래스의 shutdown() 메서드가 수행된다.
  3. HotSpot VM 레벨의 shutdown hook을 수행함으로써 HotSpot VM의 종료를 준비한다.
  4. HotSpot의 JavaThread::exit() 메서드를 호출해 JNI 처리 블록을 해제한다.
  5. HotSpot VM 스레드를 종료한다.
  6. JNI, HotSpot VM, JVMTI barrier에 있는 추적 기능을 종료시킨다.
  7. 네이티브 스레드에서 수행하고 있는 스레드를 위해 HotSpot의 “vm exited” 값을 설정한다.
  8. 현재 스레드를 삭제한다.
  9. 입출력 스트림을 삭제하고, PerfMemory 리소스 연결을 해제한다. 10.JVM 종료를 호출한 호출자로 복귀한다.

클래스 로딩 절차

  1. 주어진 클래스의 이름으로 클래스 패스에 있는 바이너리로 된 자바 클래스를 찾는다.
  2. 자바 클래스를 정의한다.
  3. 해당 클래스를 나타내는 java.lang 패키지의 Class 클래스의 객체를 생성한다.
  4. 링크 작업이 수행된다.
  5. 클래스의 초기화가 진행되며, 클래스의 static 블록과 static 필드가 가장 먼저 초기화 된다.

정리하자면, loading -> linking -> initializing 순으로 실행된다고 볼 수 있다.


참고자료 : 자바 성능 튜닝 이야기 16장 - JVM은 도대체 어떻게 구동될까?


oksusutea's blog

꾸준히 기록하려고 만든 블로그