목표
자바 소스 파일(.java)을 JVM으로 실행하는 과정 이해하기.
학습할 것
- JVM이란 무엇인가
- 컴파일 하는 방법
- 실행하는 방법
- 바이트코드란 무엇인가
- JIT 컴파일러란 무엇이며 어떻게 동작하는지
- JVM 구성 요소
- JDK와 JRE의 차이
JVM이란 무엇인가
- JVM은 Java Virtual Machine 의 약자로, 바이트 코드를 실행하기 위한 가상 머신이다.
- JVM은 자바와 운영체제 사이에서 중계자의 역할을 하며, 자바가 운영체제의 종류(Linux, Mac, ...)에 관계없이 실행 가능하도록 한다.
- JVM은 JRE(Java Runtime Environment)에 포함되어 있으며, 각 운영체제에 맞는 JRE를 설치하면 그에 맞는 JVM도 설치된다.
자바 컴파일 및 실행 방법
자바 코드를 컴파일 및 실행하기 위해서는 Windows 운영체제 기준 다음 두 소프트웨어가 필요하다.
javac.exe는 자바의 컴파일러이며, 이를 이용하여 바이트코드를 생성할 수 있다.
java.exe는 JVM을 구동시키기 위한 명령 프로그램으로, 바이트코드인 .class 파일을 실행한다.
예를 들어, 다음과 같은 Hello.java 코드가 있다.
public class Hello {
public static void main(String[] args) {
System.out.print("Hello world!");
}
}
javac를 통해 Hello.java 파일을 컴파일한다.
$ javac Hello.java
컴파일이 정상적으로 완료되면, 해당 경로에 Hello.class(바이트코드)가 생성된다.
java를 통해 바이트코드로 컴파일된 Hello.class를 실행할 수 있다.
단, 실행시에는 확장자를 붙이지 않는다.
$ java Hello
바이트코드, JIT컴파일러란 무엇인가

C나 자바같은 고급 프로그래밍 언어 (High-level programming language)는 컴퓨터 프로세서가 직접 해석할 수 없다. 따라서 이를 0과 1로 이루어진 기계어로 변환해야 한다. 즉, 기계어는 컴퓨터(하드웨어)가 직접 이해할 수 있는 0과 1로 이루어진 이진 코드이다.
바이트코드란 고급 언어인 자바와 기계어의 중간에 위치한 언어로, JVM이 이해할 수 있도록 컴파일 한 것을 말한다. 바이트코드를 거치는 이유는, 어떠한 운영체제나 개발환경에서도 실행될 수 있도록 하기 위함이다.
자바는 중간과정에서 바이트코드를 생성하고, 이를 인터프리트하는 과정을 거쳐야 하기 때문에 성능 문제가 있었다. 이를 개선하기 위해 JIT컴파일러가 등장하게 되었다.
JIT컴파일러는 Just-In-Time 컴파일러의 약자로, 프로그램을 실제 실행하는 시점에서 기계어로 번역하는 컴파일 방식을 사용한다. JIT컴파일러는 자주 사용되는 코드를 기계어로 변환하여 캐시에 저장하는데, 이로 인해 재사용 시 컴파일을 다시 하지 않아도 되고, 성능의 향상을 가져올 수 있었다.
JVM의 구성요소

JVM은 다음 4가지 구성요소로 구성되어 있다.
- Class Loader
변환된 바이트코드를 Runtime Data Area로 적재하는 역할을 한다.
- Execution Engine
Class Loader를 통해 JVM 내부로 넘어와 Runtime Data Area에 배치된 바이트코드들을 기계어로 변경하게 되는데, 이 때 JIT컴파일러 및 인터프리터가 사용된다.
- Garbage Collection
더이상 사용하지 않는 오브젝트들을 자동으로 메모리에서 제거한다.
- Runtime Data Area
프로그램을 실행하기 위해 JVM이 운영체제로부터 할당받은 메모리 공간.
1) PC Register :
스레드가 시작될 때 생성되는 메모리 공간으로, 스레드가 어떤 부분을 어떤 명령으로 실행해야할 지를 기록함.
2) Stack Area :
프로그램 실행과정에서 임시로 할당되었다가 메소드를 빠져나가면 바로 소멸되는 특성의 데이터를 저장하기 위한 영역
3) Heap Area :
new 연산자로 생성된 객체와 배열을 저장하는 메모리 공간
4) Native method stack :
Java가 아닌 다른 언어로 작성된 코드를 위한 공간
5) Method Area :
클래스와 인터페이스의 정보를 처음 메모리 공간에 올릴 때 초기화 되는 대상을 저장하기 위한 메모리 공간. 모든 스레드에 의해 공유되며, JVM이 시작될 때 생성됨.
JDK와 JRE의 차이
- JRE(Java Runtime Environment) : JRE는 말 그대로 자바 실행 환경이다. JRE는 JVM, Java binaries, Java 클래스 라이브러리 등을 포함하고 있다.
- JDK(Java Development Kit) : JDK는 자바 애플리케이션을 개발하기 위한 환경을 지원한다. JDK는 JRE를 포함할 뿐만 아니라 컴파일러(javac), javadoc, jar 등 개발에 유용한 도구들을 포함하고 있다.