자바 바이트코드(.class파일)를 실행하는 가상 머신으로, java컴파일러가 소스코드를 .class파일로 바꾸고 이를 JVM의 class loader가 JVM에 올려 소스코드를 실행한다.

소스코드를 작성
Javac가 소스코드를 .class파일로 컴파일
.class파일을 class loader가 불러와 내부 과정을 거쳐 기계어로 된 코드로 바꿔 실행
Runtime Data Area에 데이터가 저장, 수정, 삭제, 조회되며 프로그램 동작
프로세스가 동작중일 때 메모리 관리와 같은 런타임 서비스를 추가 제공(가비지 컬렉션)
자바는 런타임 클래스 참조 시점에 코드가 링크되고 로딩되는 동적 로딩을 거치는데, 클래스 로드 시스템은 런타임 중에 JVM메소드 영역에 동적으로 클래스를 로드한다.
런타임 데이터 영역에 클래스를 저장하는 것
클래스 로딩 과정을 포함해 해당 클래스 파일에 대한 검증, 준비, 해석의 세 단계를 거치는 것

로딩
자바 바이트 코드(.class)를 메소드 영역에 저장
- 클래스 정보와 부모 클래스의 정보
- 클래스의 타입(Class, Interface 등)
- 변수 메소드와 같은 필드 정보
링크
읽은 클래스가 잘 구성되어 있는지 검사
필요한 메모리할당, 데이터 구조 준비
심볼릭 메모리 레퍼런스(변수명)를 메소드 영역에 있는 실제 레퍼런스로 교체
초기화
클래스 변수들(static)을 초기화
Bootstrap
- JVM 시작 시 최초로 실행되는 로더
- Java 플랫폼의 핵심 라이브러리들을 로드
- 주로 $JAVA_HOME/jre/lib디렉토리에 있는 클래스들을 로드
- java.lang.Object, java.lang.String과 같은 클래스들 포함
Extention(or Platform)
- 부트스트랩 하위에 위치한 자식 클래스 로더
- 주로 $JAVA_HOME/jre/lib/ext디렉토리에 잇는 클래스들을 JAR파일들 로드
- javax.swing.*, javax.net.* 패키지등을 포함
- 애플리케이션 코드가 위치한 classpath를 기준으로 클래스를 로드
- 프로젝트에서 직접 작성한 클래스 파일들이나 의존성 라이브러리들을 포함
- 자바 개발자가 직접 구현하여 사용할 수 있는 로더
- 로딩 동작을 커스터마이징하거나, 요구사항에 따라 동적으로 클래스를 로드 또는 변형할 때 사용
쓰레드간 할당된 메모리 영역은 서로 침범이 불가능 하다.

+-------------------------+
| Method Area | <-- 클래스 메타데이터, 메소드 및 필드 정보, 상수 풀
+-------------------------+
| Heap Area | <-- 객체 및 배열
+-------------------------+
| Stack Area | <-- 각 쓰레드마다 존재, 메소드 호출 프레임
| +---------+ |
| | Frame | |
| |---------| |
| | Local | |
| | Variables |
| +---------+ |
+-------------------------+
| PC Register (per | <-- 각 쓰레드마다 존재, 현재 명령어 주소
| Thread) |
+-------------------------+
| Native Method Stack | <-- 각 쓰레드마다 존재, 네이티브 메소드 호출 정보
+-------------------------+
- 클래스에 대한 정보가 올라오는 영역으로 객체가 만들어질 때 모든 스레드가 해당 영역을 참조해야 하기 때문에 이 영역은 공유된다
- Runtime중에 클래스나 인터페이스 호출시 Class Loader가 해당 정보를 이 영역에 저장한다.
- 클래스 타입, 제어자, 메소드명, 인스턴스 변수 타입 등 클래스와 관련된 모든 정보가 여기에 담긴다.
- 런타임 중, 각 스레드의 Stack 영역에서 선언되어 new 연산자를 통해 만들어진 실제 인스턴스 정보가 저장되는 공유 영역이다.
- Garbage Collector는 이 영역을 정리하여 메모리를 확보한다.
- 메모리와 직결된 영역으로 OutOfMemory가 발생되기도 한다.
Stack Area(per thread)
- 지역변수, 매개변수, 리턴값 등 임시 값들이 저장되는 영역으로 스레드 생성시 스레드마다 할당된다.
- 스택은 내부적으로 Frame이란 기본 자료구조를 가지고 있다.
- 메소드 실행시 이 영역에 push되고 메소드 종료시 pop된다.
- 해당 영역이 사용가능한 크기를 넘기면 StackOverFlow가 발생
PC Register(per thread)
- 스레드 생성시 스레드마다 할당되는 영역으로 JVM이 현재 수행중인 명령어 주소를 저장한디.
- 멀티 스레드 환경에서 현재 스레드가 PC자원을 다른 스레드에게 넘겨주고 다시 받았을 때, 작업을 이어서 수행하기 위해 실행중인 명령어의 주소를 이 영역에 저장한다.
Native Method Stack(per thread)
- Native 언어인 C 또는 C++등으로 작성된 코드를 실행하기 위한 메모리 영역
- 각 스레드에서 Java메소드가 아닌 Native방식을 사용하는 메소드 실행시 이 영역을 활용한다.
- I/O, JDBC 등
Java 바이트 코드를 실제로 실행하는 핵심 컴포넌트
바이트 코드 로더
클래스 파일을 읽어들여 바이트 코드를 메모리에 로드
바이트 코드 실행
Bytecode Interpreter:
로드된 바이트 코드를 해석하여 내부 데이터 구조를 조작하고 실행
Just-In-Time Compiler(JIT):
실행되는 바이트 코드를 실시간으로 네이티브 코드로 컴파일
더 이상 사용되지 않는 객체들을 탐지, 해제하여 메모리 누수를 방지하고 프로그램 성능과 안정성을 유지시켜주는 도구
가비지 콜렉터도 일반적으로 실행엔진에 포함되어 사용된다.
Java 어플리케이션을 실행하기 위해 필요한 환경을 제공하는 플랫폼
JVM
Java 어플리케이션을 실행하는 가상머신으로 코드를 컴파일하고 실행한다.(플랫폼 독립성의 핵심)
Java Class Libraries
Java 프로그래밍에 사용되는 표준 클래스와 메소드들의 모음, 자료구조, 네트워킹, I/O등의 기능 제공한다.
Java Runtime Environment Core
JRE의 핵심 구성 요소로서, Java 어플리케이션을 실행하는 데 필요한 기본 파일과 라이브러리를 포함한다.
- rt.jar:
Java의 표준 API에 접근할 때 사용됨
Java로 소프트웨어를 개발하고 실행하기 위해 필요한 모든 도구들을 제공하는 개발 키트
JRE, JVM을 모두 포함하고 있기 때문에, JDK를 설치하면 Java 개발 환경을 구축할 수 있다.
JDK = JRE+추가 도구
Java Compiler
Java 소스 코드(.java)를 바이트 코드(.class)로 컴파일해주는 도구
Java Runtime Environment(JRE)
Java 어플리케이션 실행에 필요한 환경을 제공하는 JRE를 포함하고 있고 이 안에 JVM도 포함되어 있다.
Java Development Tools
디버깅도구, 성능 분석 도구, 프로파일러, 문서 생성 도구 등을 포함하는 개발도구
Java 어플리케이션 개발에 유용한 다양한 라이브러리와 API를 포함하는 라이브러리