
JVM(Java Virtual Machine)은 자바로 작성된 프로그램을 실행하기 위한 환경. 자바 소스코드를 CPU가 인식할 수 있는 기종 고유의 코드로 변환하여 실행한다. 그래서 운영체제에 종속받지 않고 CPU가 자바를 인식, 실행할 수 있다. JVM이 있어서 자바 언어는 운영체제에 독립적이다.
자바 응용프로그램은 운영체제나 하드웨어가 아닌 JVM하고만 통신하고 JVM이 자바 응용프로그램으로부터 전달받은 명령을 운영체제가 이해할 수 있도록 변환하여 전달한다. JVM은 운영체제에 종속적이다.
Write Once, Read Anywhere
자바 애플리케이션은 JVM을 한 번 더 거치고 하드웨어에 맞게 완전히 컴파일된 상태가 아니고 실행 시 해석(interpret)되기 때문에 속도가 느리다.

1 Classloader자바 응용프로그램을 실행할 때마다 클래스 파일(.class)들을 로드하는 JVM의 서브시스템. Java에는 세가지 빌트인 클래스로더가 있다.
Bootstrap ClassLoader : Extension ClassLoader의 상위 클래스인 첫 번째 클래스 로더. java.lange, java.net, java.util, java.io, java.sql 패키지 클래스 등과 같은 Java Standard Edition의 모든 클래스 파일이 들어 있는 rt.jar 파일을 로드한다.
Extension ClassLoader : Bootstrap ClassLoader의 자식 클래스로더이고 System ClassLoader의 부모 클래스로더. $JAVA_HOME/jre/lib/ext 디렉토리 안에 위치한 jar 파일들을 로드한다.
System/Application ClassLoader : Extension ClassLoader의 자식 클래스. classpath로부터 classfile들을 로드한다. 기본적으로 classpath는 현재 디렉토리로 세팅된다. -cp나 -classpath 명령어를 사용해 classpath를 바꿀 수 있다.
클래스로더를 만들고싶다면 ClassLoader 추상 클래스를 상속받아야 한다.
2 Class(Method) Area로드된 클래스들의 메타데이터와 관련된 정보를 저장하는 영역. 런타임 상수 풀, 필드 및 메서드 데이터, 메서드 코드와 같은 클래스별 구조가 저장된다.
3 Heap객체가 동적으로 할당되는 런타임 데이터 영역. Heap에 할당된 객체에 대한 참조는 스택 메모리에 저장된다. 전역 접근이 가능하므로 응용프로그램의 어느 곳에서나 접근할 수 있다(어떤 메서드, 클래스, 스레드).
java.lang.OutOfMemoryError를 던진다.4 Stack메서드 호출 시마다 프레임을 생성되는데 여기에 로컬 변수와 부분 결과 및 메서드 호출과 실행에 필요한 정보를 저장한다(로컬 변수, 운영 결과, 메서드 호출 정보). 메서드 호출의 순서를 관리해 프로그램의 실행 흐름이 올바르게 이어지도록 돕는다. Java에서는 멀티스레딩을 지원하기 때문에 각 스레드는 자신의 JVM 스택을 소유한다. 메서드가 호출될 때마다 새 프레임이 생성되고 프레임은 메서드 호출이 완료되면 소멸된다. Last-In-First-Out(LIFO).
java.lang.StackOverFlowError를 던진다.5 Program Counter Register(PC register)현재 실행 중인 JVM 명령어의 주소를 포함한다. 현재 실행되고 있는 바이트코드 명령어의 주소를 추적해 JVM이 프로그램의 실행 흐름을 관리하고 올바른 명령어를 순차적으로 실행할 수 있도록 돕는다. 각 스레드는 독립적인 PC 레지스터를 갖는다.
6 Native Method StackJVM 내에서 네이티브 메서드(Java가 아닌 다른 프로그래밍 언어로 작성된 메서드)를 실행하는 데 사용되는 메모리 영역. 네이티브 메서드는 시스템 수준의 작업을 수행하거나 기존 네이티브 라이브러리를 활용하기 위해 사용된다.
7 Execution EngineJava 바이트코드를 실행하는 역할. 바이트코드를 기계어로 변환하여 하드웨어가 이해할 수 있도록 한다.
8 Java Native Interface(JNI)Java 응용프로그램이 다른 프로그래밍 언어로 작성된 코드와 상호작용할 수 있게 해주는 프레임워크. Java의 이식성을 유지하면서도 성능이 중요한 부분이나 기존 네이티브 라이브러리와 통합을 가능하게 한다.