[Java] JVM (Java Virtual Machine)

2023. 1. 11. 17:02기술 창고/Java

728x90
SMALL

JVM

자바 가상 머신을 줄여서 JVM이라고 한다.

JVM은 OS(운영체제)와 Java 애플리케이션 사이의 중개자 역할을 한다.

JVM은 자바 바이트코드를 실행할 수 있는 환경을 제공해준다.

자바 원 소스 코드(java file)을 자바 컴파일러를 통해서 자바 바이트 코드로 바꾼다.(class file)

이로 인해 자바 바이트 코드가 어떠한 플랫폼에서든 독립적으로 실행될 수 있게 된다.

즉, JVM 덕분에 OS 상관없이 어디서든 Java 애플리케이션을 실행할 수 있게 되는 것이다.

 

 

 

JVM 구성

1. Class Loader (클래스 로더)

JVM 내에서 바이트 코드 (class flie)을 Loading하고, Linking을 통하여 배치하는 작업을 수행하는 모듈이다.

Runtime 시점에서 클래스를 로딩하게 해주며, 클래스의 인스턴스를 생성하면 클래스 로더를 통해 메모리에 로드하게 된다.

 

 

2. Execution Engine (실행 엔진)

로드된 클래스의 바이트 코드를 실행하는 런타임 모듈이 바로 이 실행 엔진이다.

클래스 로더를 통해 JVM 내의 Runtime Data Areas에 배치된 바이트 코드는 실행 엔진에 의해 실행되며, 실행 엔진은 자바 바이트 코드를 명령어 단위로 읽어서 실행한다.

명령어를 읽고 실행하는 방식에는 인터프리터 방식JIT compiler 방식을 사용한다.

 

 

3. Interpreter (인터프리터)

인터프리터는 프로그래밍 언어의 원 소스 코드(java file)를 바로 실행하는 프로그램이다.

원시 코드를 기계어로 번역하는 컴파일러와 대비되며, 자바는 인터프리터 방식으로 바이트 코드 명령어 단위로 읽어서 실행한다.

하지만 인터프리터 방식은 한 줄씩 수행하기 때문에 수행 속도가 느리다는 단점이 있다.

 

 

4. JIT Compiler (Just In Time Compiler)

인터프리터 방식의 단점을 보완하기 위해 JIT Compiler가 도입되었다.

JIT Compiler는 바이트코드를 컴파일하여 native code(네이티브 코드)로 변환하여 사용한다.

즉 한 번 컴파일된 코드는 빠르게 수행하게 되어 수행 속도가 빠르게 된다.

하지만 컴파일하는 과정에 비용이 들게 된다.

따라서 한 번만 수행할 코드라면 컴파일하지 않고 인터프리팅 하는 것이 유리하다.

따라서 JVM은 인터프리터 방식을 사용하다가 일정한 기준이 넘어가면 JIT 컴파일러를 사용하는 혼합 방식을 사용한다. 

 

 

5. Garbage Collector (가비지 콜렉터)

가비지 콜렉터는 유효하지 않은 메모리(Garbage)를 정리해준다.

 

 

6. Runtime Data Area

Runtime Data Area는 JVM이 프로그램을 수행하기 위해 OS로부터 별도로 할당받은 메모리 공간을 말한다.

Runtime Data Area는 크게 5가지 영역으로 나눌 수 있다.

 

ㄴ (1) PC Register

JVM의 PC Register는 CPU 내의 기억장치인 레지스터와 다르게 작동한다.

PC Register는 각 쓰레드 별로 하나씩 존재하며 현재 수행 중인 JVM Instruction의 주소를 가지게 된다.

즉, 스레드가 어떤 명령을 실행할지 기록하는 부분이라고 할 수 있다. 

 

ㄴ (2) JVM Stack

메소드(method)가 호출될 때 메서드와 메서드의 정보는 JVM Stack에 쌓이게 된다.

즉, 메서드의 매개변수(parameter), 지역 변수(local variable), return 주소, 임시 변수 등의 정보를 기록하는 스택이다.

각 스레드 별로 생성되기 때문에 다른 스레드는 접근할 수 없다. 메서드 호출이 종료되면 스택에서 정보들이 제거된다. 

 

ㄴ (3) Native Method Stack

자바 외의 언어로 작성된 네이티브 코드들을 위한 스택이다.

네이티브 코드는 앞서 말한 JIT Compiler 방식의 명령 수행을 통해 자바 바이트 코드를 네이티브 코드로 변환한다.

Java Native Interface를 통해 호출되는 C/C++ 등의 코드를 수행한다. 

 

ㄴ (4) Method Area

모든 쓰레드가 공유하는 메모리 영역으로 클래스, 인터페이스, 메서드, 필드, Static 변수 등의 바이트 코드를 보관한다. Method Area에는 Runtime Constant Pool이라는 별도의 관리 영역도 존재한다. 이는 상수 자료형을 저장하고 참조하여 중복을 막는 역할을 수행한다. 

 

ㄴ (5) Heap

Runtime 시점에 동적으로 할당하여 사용하는 영역이다.

클래스를 이용해 인스턴스를 생성하면 Heap에 저장된다.

즉, new연산자를 이용해 생성된 객체를 저장하는 영역이다.

Heap은 크게 New/Young 영역, Old 영역, Permanent Generation 3 영역으로 나뉜다.

참고로 java8 이후에는 Permanent 영역이 Metaspace 영역으로 바뀌었다.

728x90
반응형
LIST

'기술 창고 > Java' 카테고리의 다른 글

[Java] Stack / Heap  (0) 2023.01.12
[Java] 자바 컴파일 과정  (0) 2023.01.12
[Java] 동일성 (Identity) / 동등성 (equality)  (0) 2023.01.09
[Java] Java Map 내부 구현 파악  (0) 2023.01.06
[Java] Garbage Collector  (0) 2023.01.06