JVM의 구성

yanju·2022년 11월 27일
0
post-thumbnail

JVM의 구성

JVM은 클래스 로더, 실행 데이터 영역, 실행 엔진 3가지로 구성되어 있다.


클래스 로더 (Class Loader)

런타임 시점에 클래스 파일을 로딩, 연결, 초기화하는 작업을 한다.
자바는 모든 것이 클래스다.
자바 애플리케이션을 실행하기 위해서는 JVM이 컴파일된 .class 파일을 로딩해야 한다.
클래스 로더는 이 기능을 수행한다.
클래스 로더는 클래스를 메모리에 로드하고 실행을 위해 사용할 수 있게 만든다.
클래스 로딩을 최대한 효율적으로 수행하기 위해 지연 로딩, 캐싱 같은 기법을 사용한다.


실행 데이터 영역 (Runtime Data Areas)

JVM이 프로그램을 수행하기 위해 OS로부터 별도로 할당받은 메모리 공간이다.
크게 5가지 영역으로 나눈다.

  • Method Area
  • Heap Area
  • Stack Area
  • PC Registers
  • Native Method Stack

Method Area

모든 쓰레드가 공유하는 메모리 영역이다.
Method Area는 클래스, 인터페이스, 메소드, 필드, static 변수등의 바이트 코드를 보관한다.

Heap Area

프로그램 상에서 런타임시 동적으로 할당하여 사용하는 영역이다.
Class 인스턴스 생성 시 Heap에 저장한다.

Stack Area

쓰레드의 수행 정보를 Frame을 통해서 저장한다.
Stack은 쓰레드가 시작될 때 생성되고, 각 쓰레드 별로 생성이 되기 때문에 다른 쓰레드에 접근할 수 없다.
메소드가 호출되면 메소드 정보는 Stack에 쌓이고, 메소드 호출이 종료될 때 Stack point에서 제거된다.
메소드 정보는 매개변수, 지역변수, 임시변수, 메소드를 호출한 주소 등을 저장한다.
메소드 종료 시 메모리 공간이 사라진다.

PC Register

CPU내의 레지스터와는 다르게 동작한다.
Register Base가 아닌 Stack Base로 동작한다.
PC Register는 쓰레드별로 하나씩 존재하며, 현재 수행 중인 JVM 명령의 주소를 가지고 있다.
만약 Native Method를 수행하면 PC Register는 Undefined 상태가 된다.
PC Register에 저장되는 명령의 주소는 Native Pointer일 수도 있고 Method Bytecode일 수도 있다.
Native Method를 수행할 때에는 JVM을 거치지 않고 API를 통해 바로 수행하게 된다.

Native Method Stack

Java외의 언어로 작성된 네이티브 코드들을 위한 Stack이다.
JNI를 통해 호출되는 C/C++등의 코드를 수행하기 위한 Stack이다.
Native Method를 위해 Native Method Stack이라는 메모리 공간을 가진다.
프로그램에서 Native Method를 호출하면 Native Method Stack에 새로운 Stack Frame을 생성하여 푸시한다.
이는 JNI를 이용해 JVM 내부에 영향을 주지 않기 위함이다.


실행 엔진

로드된 클래스의 바이트 코드를 실행한다.
클래스 로더를 통해 JVM 내의 실행 데이터 영역에 배치된 바이트 코드는 실행 엔진을 통해 실행된다.
실행 엔진은 자바 바이트 코드를 명령어 단위로 읽어서 실행한다.
실행 엔진은 인터프리터, JIT 컴파일러, 가비지 컬렉터로 구성된다.

인터프리터

인터프리터는 자바 컴파일러에 의해 변환된 자바 바이트 코드를 읽고 해석한다.

JIT 컴파일러

런타임에 바이트 코드를 실제 기계어로 변환한다.

가비지 컬렉터 (GC)

자바 프로그램 내부에서 사용되지 않는 메모리를 자동으로 회수하는 역할을 한다.
개발자에게 메모리 관리에 대한 부담을 덜어준다.

0개의 댓글