JVM이란?
JVM(Java Virtual Machine), 자바 가상 머신으로 자바 바이트 코드를 실행하는 기계를 말한다. JVM은 자바와 운영체제 사이 중개자 역할을 수행하여 운영체제에 구애받지 않고 자바를 프로그램을 실행할 수 있도록 한다.. 또한, Garbage Collection을 수행한다.
JVM이 중요한 이유?
한정된 메모리를 효율적으로 사용하여 최고의 성능을 내기 위해서는 JVM을 필수로 알아야 한다. 동일한 프로그램이더라도 메모리 관리에 따라 성능이슈가 천차만별이기 때문에, JVM을 학습하여 메모리를 효율적으로 관리할 수 있도록 하자.
JVM의 구성
1. Class Loader
Java 컴파일러가 컴파일한 클래스(.class)파일을 로드하고, 링크를 통하여 배치하는 작업을 수행하는 모듈이다(자바 애플리케이션이 실행중일 때 동작한다). jar파일 내 저장된 클래스들을 JVM위에 탑재하고(Runtime Data Area로) 사용하지 않는 클래스들은 메모리에서 삭제한다. 즉, 클래스를 처음으로 참조할 때, 해당 클래스를 로드하고 링크하는 역할까지 맡는다.
2. Execution Engine
Class Loader에 의해 메모리(Runtime Data Area)로 적재된 클래스(바이트 코드)를 기계어로 변경해 명령어 단위로 실행하는 역할을 한다. 이 때 명령어를 수행하는 방식은 두가지가 존재한다.
- Interpreter(인터프리터) 방식 : 한 줄씩 명령어를 읽어 수행하는 방식.
- JIT(Just-In-Time) 방식 : 인터프리터 방식의 단점을 보완하기 위해 도입된 컴파일러.인터프리터 방식으로 진행되다가 적절한 시점에 바이트코드 전체를 컴파일하여 네이티브 코드로 변경하고, 이후에는 이 네이티브 코드를 직접 실행하는 방식이다.
3. Garbage Collector
Heap 메모리 영역에 적재된 객체들 중, 더이상 참조되지 않는 객체를 찾아 제거하는 역할을 한다. GC수행시 모든 쓰레드가 일시 정지되며, 정확한 수행 시간은 언제인지 알 수 없다.
4. Runtime Data Area
JVM이 자바 애플리케이션을 실행할 때 사용되는 데이터를 적재하기 위해 OS에서 할당받은 메모리 공간이다. 자바 바이트 코드를 실행할 때 여러가지 종류의 메모리 공간이 필요한데 그것을 담는 공간이다. 세부 항목은 아래와 같다.
1) PC Register
Thread가 시작될 때마다 생성되며, program counter, 즉 thread가 실행하는 부분의 주소와 명령을 저장하고 있다.(즉 바이트코드의 몇번째 줄을 실행하고 있는지 나타내는 역할)
2) JVM 스택 영역
스택 영역은 메소드가 호출 될 때마다 생성한다.
지역변수, 파라미터, 리턴 값, 연산 등에 사용되는 임시적인 값들을 저장하는 영역이다. 프로그램 과정에서 임시로 할당되었다가 메소드 실행 종료시 바로 소멸되는 특성을 가진 데이터를 저장하는 공간이다.
3) Native Method Stack
자바가 아닌 다른 언어로 작성된 코드를 위한 공간이다. JAVA Native Interface를 통해 바이트 코드로 전환하여 저장하게 되며, 일반 프로그램처럼 커널이 스택을 잡아 독자적으로 프로그램을 실행하는 영역이다.
4)Method Area(=Static Area)
클래스 정보를 처음 메모리 공간에 올릴 때 초기화 되는 대상을 저장하기 위한 메모리 공간이다. 클래스 멤버 변수의 이름, 데이터 타입, 접근제어자 정보와 같은 필드 정보(Field Information)나 메소드의 이름, 리턴타입, 매개변수, 접근제어자에 대한 정보(Method Information)도 저장하고, class/interface여부, super class의 이름(Type Information)도 저장한다. 즉, 클래스 데이터를 위한 정보는 이 영역에 모두 저장된다고 보면 된다.
5) Heap Area
프로그램을 실행하며 생성된 모든 객체를 저장하는 가상 메모리 공간이다. new연산자로 생성된 객체와 배열을 저장한다.위 메소드 영역에 로드된 클래스만 생성이 가능하다. 이 Heap 영역은 크게 세가지로 분류된다.
- Permanent Generation : 생성된 객체들의 정보와 주소값이 저장되는 공간.
-
New/Young 영역
- Eden : 새롭게 할당된 데이터가 쌓이는 곳으로 일정주기 동안 참조되면 Survivor로 옮겨진다. Survivor로 옮겨지지 못한 데이터는 GC에 의해 소멸된다.
-
Supervivor 0 / 1 : Eden에서 참조되는 객체들이 저장되는 공간이다. 참조가 살아있는 경우 주기에 맞춰 다른 Survivor 영역으로 이동하고, 그렇지 못한 데이터들은 GC에 의해 소멸된다. 이러한 과정을 Minor GC라고 한다.
- Old 영역 : Survivor 영역에서 오래 살아남은 데이터는 Old 영역으로 넘어간다. Old영역은 이렇게 넘어온 데이터가 많아 Young크기보다 크게 설계되며, 이 부분에서 발생한 GC는 Major GC라고 한다.
Thread를 기준으로, 1번~3번(PC Register, 스택영역, Native Method Stack)은 각각의 쓰레드마다 생성되며, 4번~5번은 모든 쓰레드가 공유한다.
참고 자료 :