Java

[Java] - JVM의 구성요소와 메모리 구조

영지는 달리는중 2020. 11. 15. 23:47

JVM 구성 요소

1. Class Loader

JVM 내로 클래스 파일을 load하고 link를 통해 배치를 수행하는 모듈로 Runtime 시에 동적으로 클래스를 로드한다. 

자바는 동적 코드, 컴파일 타임이 아니라 런타임에 참조한다. 즉, 클래스를 처음으로 참조할 때 해당 클래스를 load하고 link한다.

 

2. Execution Engine

class loader를 통해 배치된 클래스를 실행시킨다. 클래스 파일(바이트 코드)은 비교적 인간이 보기 쉬운 형태이기 때문에 기계가 실행할 수 있는 형태로 변경시키는데 이 때, 두 가지 방식을 사용한다. ( 인터프리터, JIT )

 

3. Interpreter

실행 엔진은 바이트 코드를 명령어 단위로 실행한다. 이는 한 줄 씩 수행하기 때문에 느리다는 단점을 가지고 있다.

 

4. JIT (Just In Time) Compiler

Interpreter 방식의 단점을 보완하기 위해 도입된 방식으로, Interpreter 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일 하여 네이티브 코드로 변경하고, 더 이상 Interpreting 하지 않고 네이티브 코드로 직접 실행하는 방식이다.

네이티브 코드는 캐시에 보관되기 때문에 한 번 컴파일된 코드는 빠르게 실행할 수 있다. 물론 한 번만 실행되는 코드라면 JIT 보다 Interpreter 방식이 유리하다. 따라서 JVM은 해당 메소드가 얼마나 자주 수행되는지 체크하고, 일정 정도를 넘을 때 컴파일을 수행한다.

 

5. Garbage Collector

동적으로 할당된 메모리 중 사용되지 않는 메모리를 반환한다. 실행 시기는 JVM이 OS에 메모리를 추가적으로 요청했을 때 실행되고,24시간 내내 돌아가는 서버 프로그램의 경우, JVM이 한가한 시점에 실행된다.

 

JVM 메모리 구조 (Runtime Data Area)

프로그램이 실행되면, JVM은 OS로 부터 프로그램을 수행하는데 필요한 메모리를 할당 받고,

JVM은 메모리를 용도에 따라 여러 영역으로 나누어 관리하게된다. 

 

1. Method Area (메소드 영역)

프로그램 실행 후, 어떤 클래스가 사용 되면 JVM은 해당 클래스의 클래스 파일(*.class)을 읽고 분석하여

클래스에 대한 정보들을 이곳에 저장한다. 이 때, 해당 클래스의 클래스 변수도 함께 저장된다.

 

2. Call Stack 또는 Execution Stack (호출 스택)

메소드 작업에 필요한 메모리 공간을 제공한다.

메소드가 호출되면, 호출 스택에 메소드를 위한 메모리가 할당되며 메소드가 작업을 마치면 반환되어 비워진다.

제일 위에 있는 메소드가 현재 실행 중인 메소드이고, 바로 아래의 메소드가 위의 메소드를 호출한 메소드이다.

 

3. Heap

프로그램 실행 후, 생성 되는 모든 인스턴스가 이곳에 생성된다. 즉, 인스턴스 변수들이 생성되는 공간

 

4. PC Register

CPU의 Register와 역할이 비슷하다. 현재 수행중인 JVM 명령의 주소값이 저장된다. (각 Thread별로 하나씩 생성)

5. Native Method Stack

다른 언어(C/C++ 등)의 메소드 호출을 위해 할당되는 구역으로 언어에 맞게 Stack이 형성되는 구역이다.

참고 블로그

참고 블로그(2)