JVM 구조
JVM, JRE, JDK
- JVM
- 자바 소스 코드로 부터 만들어지는 바이너리 코드 파일(.class)을 클래스 로더로 부터 읽어들여 실행한다.
- JRE
- JVM 의 실행환경을 구현하기 위해 자바 API 와 JVM 으로 구성되어 있다.
- JDK
- 자바 개발도구 이며, JRE, javac, java 등을 포함한다.
Hotspot JVM 아키텍쳐

클래스 로더
자바는 런타임에 클래스를 처음으로 참조할 때, 해당 클래스를 로드하고 링크한다.

- Bootstrap Class Loader
- JVM이 시작되면, 부트스트랩(bootstrap) 클래스로더를 생성하고, 그 다음에 가장 첫번째 클래스인 Object를 비롯해 자바 API 를 로드한다.
- Extension Class Loader
- 다양한 보안 확장 기능 같은 확장 클래스들을 로드한다. ( jre/lib/ext 등 )
- System Class Loader
- 사용자가 지정한 $classpath 내의 클래스를 로드한다.
- User-Defined Class Loader
- 애플리케이션 사용자가 직접 코드 상에서 생성해서 사용하는 클래스 로더이다.
런타임 데이터 영역

PC Register, JVM Stack, Native Method Stack 는 스레드마다 생성되며, 힙, 메서드 영역, 런타임 상수 풀은 모든 스레드가 공유해서 사용한다.
- Program Counter Register
- 스레드마다 생성되며, 현재 실행 중인 JVM 명령의 주소가 저장된다.
- JVM 스택
- 스레드마다 생성되며, 메서드가 실행될 때 마다 하나의 스택프레임을 생성되는데, 해당 스택 프레임을 저장하기 위한 장소이다.
- 스택 프레임
- 각 스택 프레임은 지역변수 배열, 피연산자 스택, 런타임 상수풀에 대한 레퍼런스를 가진다.
- 지역변수 배열
- 0 부터 시작하는 인덱스를 가진 배열이다. 0은 메서드가 속한 클래스 인스턴스의 this 레퍼런스이고, 1부터는 메서드에 전달된 파라미터가 저장되며, 이후부터는 메서드의 지역 변수가 저장된다.
- 피연산자 스택
- 메서드의 실제 작업 공간이다. 각 메서드는 피연산자 스택과 지역 변수 배열 사이에서 데이타를 교환하고, 호출 결과를 추가하거나 꺼낸다.
- 상수풀 참조
- 네이티브 메서드 스택
- 자바 이외의 언어로 작성된 네이티브 코드를 위한 스택이다.
- 메서드 영역
- 모든 스레드가 공유하는 영역이며, JVM 이 시작될 때 생성된다. 각 클래스와 인터페이스에 대한 런타임 상수풀, 필드와 메서드 정보, 스태틱 변수, 메서드의 바이트 코드 등을 보관한다. 흔히 Permanent Area ( PermGen ) 이라고 한다.
자바 8 에서는 Perm 영역이 사라지고 metaspace 로 변경되었으며, 스태틱 변수는 heap 으로 이동되었다.
Metaspace 는 heap 공간을 사용하지 않으며, native 메모리 영역을 사용한다.
MaxMetaspaceSize 에 도달하면 GC 가 시작된다.
- 런타임 상수풀
intern 된 스트링(string’s pool)은 heap 에 저장된다.
- 각 클래스와 인스턴스의 상수 뿐만이 아니라, 메서드와 필드에 대한 모든 레퍼런스를 담고 있다. 즉 어떤 메서드나 필드를 참조할 대, JVM 은 런타임 상수 풀을 통해 해당 메서드나 필드의 실제 물리적인 메모리 상의 주소를 찾아내서 참조하기 위해 사용한다.
- 힙
실행엔진
JIT 컴파일러
자바의 성능을 개선하기 위해 JIT 컴파일러를 만들었고, 이름을 HotSpot 으로 지었다. JIT 컴파일러는 프로그램의 성능에 영향을 주는 지점에 대해서 ‘바이트 코드를 컴파일하고 실행 가능한 네이티브 코드로 변환’ 한다.