Java Virtual Machine, JVM

Janice._.oooh·2021년 11월 29일
0

Android/Java

목록 보기
8/8
post-thumbnail

JVM이란?


JAVA Virtual Machine(이하JVM)라는 뜻으로 자바 가상 머신을 뜻합니다.

가상머신: 프로그램을 실행하기 위해 물리적 머신과 유사한 머신을 소프트웨어로 구현

JVM은 클래스 로더를 통해 애플리케이션을 읽어 JAVA API와 함께 실행합니다.

일반적인 프로그램은 Window 또는 Linux와 같은 OS위에서 실행됩니다. 하지만 JAVA프로그램은 OS위의 JVM에서 실행 즉, JAVA와 OS사이의 중개자 역할을 수행함으로써 JAVA가 OS에 구애받지 않고 재사용을 가능하게 해줍니다.

또한 메모리관리, Garbage Collection 등을 수행합니다.
C언어의 경우에는 직접 메모리를 할당 및 해제하여야 하지만 JAVA에서는 JVM이 자동으로 메모리 관리를 해주는 장점이 있습니다.



JAVA프로그램 실행 과정


  1. 프로그램이 실행되면 JVM은 OS로부터 해당 프로그램이 필요로하는 메모리를 할당받아, 메모리를 용도에 맞게 여러 영역으로 나누어 관리합니다.
  2. JAVA Complier(javac)가 JAVA Source(.jvava)를 읽어들여 JAVA Byte Code(.class)로 변환시킵니다.
  3. Class Loader를 통해 class 파일들을 JVM으로 로딩합니다.
  4. 로딩된 class 파일들은 Execution Engine을 통해 해석됩니다.
  5. 해석된 Byte Code는 Rumtime Data Areas에 배치되고 수행이 이루어 집니다. 이러한 과정에서 필요에 따라 JVM은 Garbage Collection과 같은 관리 작업도 수행합니다.

JAVA Compiler

JAVA Source(.java)를 JAVA Byte Code(.class)로 변환 하는 역할을 합니다.

Class Loader

JAVA Byte Code(.class)들을 읽어 JVM의 Execution Engine이 사용할 수 있도록 Rumtime Data Area에 배치합니다.
jar파일 내에 저장된 클래스들을 JVM위에 탑재하고 사용하지 않는 클래스들은 메모리에서 삭제합니다. 자바는 동적 코드, Compil time이 아니라 Runtime에 참조합니다. 즉, 클래스를 처음으로 참조할 때, 해당 클래스를 load하고 link하게됩니다.

Execution Engine

Execution Engine(실행 엔진)은 클래스를 실행키시는 역할을 합니다.
JAVA Byte Code는 비교적 인간이 보기 편한 형태의 코드로, 이를 JVM내부에서 기계가 실행 할 수 있는 형태로 변경합니다.

Execution Engine은 두 가지 방식을 사용하게 됩니다.

1. Interpreter
JAVA Byte Code를 명령어 단위로 읽어 바로바로 처리하지만, 한 줄씩 수행하여 속도가 느린 단점이 존재합니다.

2. JIT(Just-In-Time)
Interpreter의 단점을 보완하기 위해 도입된 컴파일러로서 Interpreter방식으로 수행하다 적절한 시점에 Byte Code 전체를 컴파일하여 Native Code로 변경하고 이 후, 더 이상 Interpreting하지 않고 계속해서 Native Code로 직접 실행하는 방식입니다.(Native Code는 Cache에 보관하므로 한 번 컴파일된 코드는 빠르게 수행됩니다.)

하지만, JIT방식은 Interpreter보다도 훨씬 오래걸리기때문에 한 번만 실행되는 코드의 경우엔 Interpreting방식이 유리합니다. 따라서 JVM은 내부적으로 해당 메서드의 사용 빈도를 체크하고 JIT컴파일을 진행합니다.

Rumtime Data Area

프로그램을 수행하기위해 OS에서 할당받은 메모리 공간으로 5개의 영역으로 나누어 집니다.
PC Register, JVM Stack, Native Method Stack은 Thread마다 하나씩만 생성되며
Heap, Method Area는 모든 Treads가 공유하여 사용합니다.

1. PC Register
Thread가 시작될 때 생성됩니다.
그리고 Thread가 어떤 명령어로 실행되어야 하는지에 대한 기록을 하며 현재 수행중인 JVM명령의 주소를 갖습니다.

2. JVM Stack
프로그램 실행과정에서 임시로 할당되었다가 Method가 종료되면 바로 소멸되는 데이터 저장 영역입니다.
지역변수, 매개변수, 메서드정보, 연산 도중 발생하는 임시 데이터 등이 저장됩니다. Method호출 시마다 각각의 스택 프레임(해당 Method만을 위한 공간)이 생성되고 메서드 수행이 끝나면 프레임 별로 삭제합니다.

3. Native Method Stack
JVM은 네이티브 방식을 지원합니다. 따라서 Thread에서 네이티브 방식의 Method가 실행되는 경우 Native Method Stack에 쌓이게 됩니다. 즉, 일반적인 Method를 실행하는 경우엔 JVM Stack에 쌓이고 해당 Method내부에 네이티브 방식의 Method가 존재한다면 Native Stack에 쌓입니다.

4. Heap
객체생, 배열 등과 같이 동적으로 할당되는 데이터가 저장되는 영역입니다. Heap에 할당된 데이터들은 Garbage Collection의 대상이 되며, JVM 성능의 이슈에서 가장 많이 언급되는 공간이기도 합니다.

5. Method Area ( =Class Area, Code Area, Static Area)
모든 Thread가 공유하는 영역으로 JVM이 시작될 때 생성됩니다. JVM이 읽어들인 각각의 class와 interface에 대한 Runtime 상수 풀, 필드와 메서드 코드, Static변수, 메서드의 바이트 코드 등을 보관합니다.



Reference)

0개의 댓글