본문 바로가기

Java

JVM은 어떻게 동작하는가?

Introduction

JVM(Java Virtual Machine)은 JRE(Java Runtime Environment)의 한 부분으로, Java 어플리케이션을 실행시키는 런타임 엔진이다. JVM은 소스코드 상의 main() 메소드를 호출하여 프로그램을 실행시킨다.

처음 자바를 접해본 사람이라면 JVM, JRE, JDK 등의 용어가 혼동이 되는 경우가 많다. 이를 위해 짧게 정리를 해보자면 아래와 같다.

- JVM (Java Virtual Machine): 자바 클래스파일들을 로딩하여 어플리케이션을 수행시키는 가상 머신

- JRE (Java Runtime Environment): 자바 구동 환경. JVM + 시스템 라이브러리

- JDK (Java Development Kit): 자바 개발 키트, JRE + 컴파일러 (javac), Debugger등의 개발 도구들을 포함

 

 

Java에 대해서 처음 공부를 할 때 배우는 것들 중 하나는, 자바는 시스템 환경에 종속적이지 않다는 점이다. 이는 WORA(Write Once Run Anywhere)라고도 칭하며, 한번 작성된 코드는 특별한 추가적인 처리 없이 어느 시스템에서든 정상적으로 실행될 것이 보장된다는 뜻이다. 이것을 가능하게 하는 것이 바로 JVM이다.

*.java 파일이 실행되는 과정

Java로 *.java file을 작성하고, 이를 compile하면 java bytecode로 이루어진 동일한 이름의 *.class를 생성한다. 이 *.class 파일을 각 OS에서 JVM이 로딩하여 프로그램을 실행시키게 된다. 각 OS는 platform dependent 한 JRE를 가지고, 이것이 Java가 platform independent하게 모든 OS에서 수행될 수 있는 기반이 된다.

 

JVM Architecture

JVM의 대략적인 구조는 아래와 같다. 

JVM Architecture

JVM Memory

- Method Area: 메소드 영역은 JVM에 단 하나만 존재하며, 모든 스레드들에 의해 공유된다. 메소드 영역에는 클래스명, 부모 클래스명, 메소드, static 변수 정보 등 모든 class level의 정보들이 저장되어 있다.

- Heap: 모든 object들에 대한 정보가 저장되어 있다. 모든 스레드들에 의해 공유되는 영역이다.

- Stack: 스레드당 한개가 할당되는 공유되지 않는 영역이며, 스레드가 생성되는 시점에 동시에 생성된다. stack은 frame이라는 block을 기준으로 구분되며, 이는 activation record라고도 불리며 method call 을 저장한다. 해당 메소드에서 생성된 로컬 변수는 모두 해당 프레임에 저장이 된다. 스레드가 종료되면 해당 스레드의 runtime stack은 JVM에 의해 파괴된다.

- PC Register: 각각의 스레드가 별개의 PC를 가지고 있으며, 현재 수행중인 JVM instruction의 주소를 저장한다.

- Native Method Stacks: Native code들의 instruction을 가지고 있다. Java가 아닌 다른 언어로 쓰여져있다.

 

Class Loader

클래스로더는 크게 1) Loading, 2) Linking, 3) Initialization 세 가지 일을 수행한다.

Loading

클래스 로더는 *.class file을 읽어 그에 맞는 byte code를 생성하여 이를 메소드 영역에 저장한다. 이 때 저장하는 정보들은 아래와 같다

1. 로딩된 *.class의 FQN (Fully Qualified Name)와 부모 클래스 정보

2. 로딩된 *.class가 Class, Interface, Enum인지

3. Modifier, 변수, 메소드 정보

클래스 로딩이 완료되고 나면, JVM은 java.lang.Class type object를 생성하여 Heap에 저장한다. 이는 자바의 최상위 클래스인 Object의 getClass()를 통해서 얻을 수 있다.

Linking

Verification, Preparation, Resolution 세 가지의 일을 수행한다.

- Verification: *.class file의 correctness를 체크

- Preparation: JVM이 클래스 변수들을 위한 메모리를 할당하고, default value들로 initialize한다. 

- Resolution: 타입의 Symbolic reference를 direct reference로 대체한다. 참조된 엔티티를 찾기 위해 메소드 영역을 탐색한다.

Initialization

static 변수들이 코드에 지정된 값들로 assign된다. class hierarchy에서 top down 방식으로 수행된다.

 

Class Loader의 종류

1. Bootstrap Class Loader: $JAVA_HOME/jre/lib directory에 있는 Core JAVA API 클래스들을 로딩한다. C, C++로 짜여져 있으며, path는 bootstrap path라고 불린다.

2. Extension Class Loader: $JAVA_HOME/jre/lib/ext(Extension path) 나 java.ext.dirs 이라는 시스템 property에 명시되어있는 path에 있는 클래스들을 로딩한다. (sun.misc.Launcher$ExtClassLoader)

3. Application Class Loader: Application class path에 있는 클래스들을 로딩한다. java.class.path라는 environment variable을 이용한다. sun.misc.Launcher$ExtClassLoader 로 구현되어있다.

 

Execution Engine

Execution Engine은 *.class (bytecode)를 실행시킨다. 이는 byte code를 line-by-line으로 읽어서 수행시킨다. 이는 크게 세 가지 부분으로 나뉜다.

1. Interpreter: Bytecode를 line-by-line으로 interpret하고 실행시킨다. 

2. Just-In-Time Compiler (JIT): Interpreter의 효율성을 증대시키기 위해 사용된다. Interpreter는 한줄씩 읽기 때문에, 같은 코드가 여러 줄에 걸쳐 반복이 될 때 매번 똑같은 작업이 수행된다는 비효율이 있다. 이같은 비효율을 줄이기 위해, JIT는 중복되는 메소드 콜에 대해 바이트코드 전체를 컴파일하여 native code로 바꾸어 반복되는 메소드 호출을 direct native code로 대체한다.

3. Garbage Collector: 참조가 없는 객체들을 destroy시킨다. GC 에 대해서는 다른 글에서 따로 다루어보도록 한다. 

Java는 다른  컴파일 언어들에 비해 다소 느리며, 컴파일 언어이지만, 동시에 인터프리터 언어의 성격도 지닌다는 평가를 받는다. 이는 위에서 설명한 바와 같이, execution engine의 runtine interpreter가 java byte code를 로딩하여 실행 시점에 한줄 한줄씩 이 byte code를 native machine code로 바꾸어 실행시키기 때문이다. 

 

References

 

1. https://www.geeksforgeeks.org/jvm-works-jvm-architecture/

 

How JVM Works - JVM Architecture? - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

2. https://www.guru99.com/java-virtual-machine-jvm.html

 

Java Virtual Machine (JVM) & its Architecture

In this tutorial, you will learn- How to use Conditional Statements Different Types of Conditional...

www.guru99.com

3. stackoverflow.com/questions/41554714/are-different-os-jres-different

 

Are different OS JRE's different?

I am questioning to myself if JRE's from different OS's (For example; Windows, Linux, Mac, etc) are all different and platform dependent? The reason I ask this is because if Java Bytecode is platform

stackoverflow.com