What is JVM?
- 자바 가상 머신(Java Virtual Machine, JVM)은 시스템 메모리를 관리하면서 자바 기반 어플리케이션을 위해 이식 가능한 실행 환경을 제공한다.
- 자바 프로그램이 어느 기기, 또는 어느 운영체제 상에서도 실행될 수 있게 하는 것과 프로그램 메모리를 관리하고 최적화해준다.
- 자바 바이트 코드(
.class
)를 실행할 수 있는 주체로 JVM 덕분에 CPU나 운영체제가 독립적으로 동작 가능하다.
JVM의 구조
- 실행될
.class
파일을 메모리에 로드 후 초기화 작업 수행한다.
- 메소드와 클래스 변수들을 해당 메모리 영역에 배치한다.
- 클래스 로드가 끝난 후 JVM은
main()
메소드를 찾아 지역변수, 객체변수, 참조변수를 스택에 쌓는다.
Class Loader
- 자바 컴파일러가
.java
파일을 컴파일하면 .class
파일(자바 바이트 코드)이 생성된다.
- 이렇게 생성된
.class
파일들을 엮어 Runtime Data Area 형태로 메모리에 적재하는 역할을 한다.
- 클래스 로딩을 위한 JVM의 로딩 절차
- 어떤 메소드를 호출하는 문장을 만났는데, 그 메소드를 가진 바이트 코드가 아직 로딩된 적이 없다면, 곧바로 JVM은 JRE 라이브러리 폴더에서 클래스를 찾는다.
- 없으면 CLASSPATH 환경 변수에 지정된 폴더에서 클래스를 찾는다.
- 찾았으면 그 클래스 파일이 올바른지 바이트 코드 검증
- 올바른 바이트 코드라면 메소드 영역으로 파일을 로딩
- 클래스 변수를 만들라는 명령어가 있으면 메소드 영역에 그 변수를 준비한다.
- 클래스 블록이 있으면 순서대로 그 블록을 실행한다.
- 이렇게 한번 클래스의 바이트 코드가 로딩되면 JVM이 종료될때까지 유지된다.
Execution Engine
- Class Loader를 통해 JVM 내의 런타임 데이터 영역에 배치된 바이트 코드(
.class
)를 실행한다.
- 이때, 자바 바이트 코드를 명령어 단위로 읽어서 실행한다.
Garbage Collector
- 힙 메모리 영역에 존재하는 객체들 중에 생존 여부를 판단하여 더 이상 사용되지 않는 객체를 제거하는 방식으로 메모리를 자동 관리한다.
Runtime Data Area
- JVM이 운영체제 위에서 실행되면서 할당받는 메모리 영역이다. Class Loader에서 준비한 데이터들을 보관하는 저장소이다.
Runtime Data Area
Method(Static) Area
- JVM이 읽어들인 클래스와 인터페이스, 런타임 상수 풀, 멤버 변수(필드), 클래스 변수(Static 변수), 생성자와 메소드를 저장하는 공간
Runtime Constant Pool
- 각 클래스와 인터페이스의 상수 뿐만 아니라, 메소드와 필드에 대한 모든 Reference까지 담고 있는 테이블이다.
- 즉, 어떤 메소드나 필드를 참조할 때, JVM은 런타임 상수 풀을 통해 메소드나 필드의 실제 메모리 상 주소를 참조하여 중복을 막는 역할을 한다.
Heap Area
- JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 영역이다.
new
연산자로 생성된 객체 또는 인스턴스와 배열을 저장한다.
- 힙 영역에서 생성된 객체와 배열은 스택 영역의 변수나 다른 객체의 필드에서 참조한다.
- 참조하는 변수나 필드가 없다면 의미 없는 객체가 되어 GC의 대상이 된다.
Stack Area
- 각 스레드마다 하나씩 존재하며, 스레드가 시작될 때 할당된다.
- 메소드를 호출할 때마다 프레임(Frame)을 추가(push)하고 메소드가 종료되면 해당 프레임을 제거(pop)하는 동작을 수행한다.
- FILO (First In Last Out) 구조로 push와 pop 기능 사용
- 메소드 호출 시 생성되는 스레드 수행정보를 기록하는 Frame을 저장
- 메소드 정보, 지역변수, 매개변수, 연산 중 발생하는 임시 데이터 저장
- 기본(Primitive) 타입 변수는 스택 영역에 직접 값을 가진다.
- 참조 타입 변수는 힙 영역이나 메소드 영역에 Reference를 가진다.
- 힙 영역에 있는 객체가 스택 영역에서 참조할 수 없는 경우 GC의 대상이 된다.
PC Register
- 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 생성된다.
- 스레드가 어떤 명령어로 실행되어야 할지에 대한 기록을 하는 부분으로 현재 수행중인 JVM 명령의 주소를 갖는다.
Native Method Stack Area
- 자바 외 언어로 작성된 네이티브 코드를 위한 Stack 메모리 영역이다.
References