VM (Virtual Machine) 이란?
프로그램 실행을 위해 물리적 머신과 유사한 소프트웨어를 가상 머신이라고 한다. 소프트웨어로 구성된 하드웨어(머신)을 의미한다. 1960년대 중반 처음 개발되어 메인 프레임의 중요한 부분으로 자리 잡았다.
가상 머신을 사용하는 이유는 다음과 같다.
- 격리와 보안 중요도 증가
- 표준 운영체제 보안성과 신뢰성 실패
- 클라우드 컴퓨팅과 같이 많은 사용자가 한 컴퓨터를 공유
JAVA Virtual Machine
VM은 프로그램 실행을 위한 소프트웨어 가상 머신, 자바 가상 머신은 자바 실행을 위한 가상 머신으로 생각하면 된다.
자바의 실행을 위해서 사용하는 JVM은 어떤 방식으로 동작될까?
먼저 자바는 운영체제에 종속적이지 않다는 사실을 알아야 한다. 자바를 설명할 때 "한번 동작하면 어디서나 실행된다. write once, run anywhere" 이라는 말을 붙이기도 한다. 자바는 어떤 운영체제에도 실행할 수 있다. 특정 운영체제에 따라서 실행이 나뉘지 않는 이유는 JVM이 있어서 가능한 일이다.
JVM에 대해서 먼저 설명하기 전에 JDK 구조를 알아보자.
JDK (Java Development Kit)
JDK는 자바 개발을 위한 도구 모음이다. 자바를 처음 시작할 때, jdk를 설치하면서 시작한다. 자바는 하나의 프로그래밍 언어이다. c언어를 배울 때 우리는 c언어를 설치하지 않는다. c기반의 c++과 c#을 설치하지 않고, js를 사용할 때도 자바스크립트를 설치한다라는 문장은 사용하지 않는다. 그저 IDE를 설치해 사용하고자 하는 언어를 선택해서 사용한다.
그런데 자바를 사용할 때는 JDK를 설치해야만 한다. 이는 파이썬을 설치하는 이유와 같다. 모든 운영체제 위에서 우리가 사용할 수 있는 언어를 실행시키기 위한 과정이다.
JDK 구조

1. JRE (Java Runtime Environment)
자바 실행 환경의 약자로, 실행을 위한 최소한의 환경을 제공하는 것이다. JRE에는 JVM과 자바 라이브러리가 포함되어 있다. 자바 라이브러리에는 개발 시 필요한 클래스가 들어있어 우리가 사용하는 각 라이브러리는 이 JRE에 포함되어 있는 것이다.
2. JVM (Java Virtual Machine)
이 포스팅의 주제이자, JRE에 포함되어 있는 JVM은 자바를 실행하는 가상 머신이다. 모든 자바 코드는 이 JVM 위에서 실행된다. JVM은 원시 코드(.java)인 자바 코드를 컴파일러를 통해 자바 바이트 코드(.class)로 변경한다. 자바 바이트 코드를 운영체제가 이해할 수 있도록 기계어로 번역한다.
바이트 코드: 가상 머신이 이해할 수 있는 중간 코드
JDK를 설치하면서 JRE가 자동으로 함께 설치되고, 그 안에 있는 JVM 덕분에 자바는 모든 운영체제 위에서 동작할 수 있다. 자바 코드가 각 운영체제에 맞춘 기계어로 변환할 수 있는 건 모두 JVM덕분이다. JVM은 어떻게 기계어로 변환할까?
JVM 구조

1. 클래스로더 Class Loader
JVM은 클래스로더를 통해 코드를 읽어 자바 API와 함께 실행한다. 자바는 런타임에 각 클래스를 불러온다. 프로그램이 실행되는 런타임 도중에 JVM 메소드 영역에 Java클래스를 로드하는 것이다. 이 역할을 클래스로더가 맡는다.
1) 로딩
자바 바이트 코드(.class)를 메소드 영역에 저장한다.
2) 링크
클래스가 자바 명세를 지켰는지 검증한다.
메모리를 할당하고 정의된 데이터 구조로 준비한다.
symbolic reference(참조하는 대상의 이름)를 실제 레퍼런스로 교체하는 분석 단계로 마무리한다.
3) 초기화
클래스 변수를 적절한 값으로 초기화한다.
2. 실행 엔진 Execution Engine
클래스로더가 런타임 영역에 자바 바이트 코드를 배치하면 실행하는 역할을 한다. 자바 바이트 코드 자체로는 운영체제가 이해할 수 없다. 이 자바 바이트 코드를 기계어로 번역해야 하는데, 실행 엔진에서 번역을 맡는다.
1) 인터프리터 Interpreter
자바 바이트 코드를 명령어 단위로 한줄씩 읽어서 실행한다.
2) JIT (Just-In-Time)
JIT compliation, dynamic translation이라고도 불리는 JIT는 인터프리터 방식에서 더 나아간 실행 방식이다. 인터프리터 방식으로 일정 시간 실행하다가, 적절한 시점에 바이트 코드 전체를 컴파일한다. 전체를 기계어로 변경하고 난 뒤, 기계어로 직접 실행한다.
기계어로 실행한 코드는 캐시에 보관하여, 한번 컴파일이 되면 그 뒤에는 수행이 빨라진다.
하지만 모든 코드를 한번에 컴파일하기 때문에, 한줄씩 실행하는 인터프리터보다 오랜 시간이 걸린다.
3) 가비지 컬렉터 Garbage Collector)
더 이상 사용되지 않는 인스턴스를 메모리에서 삭제한다.
3. 런타임 영역 Runtime Data Area

1) PC Register
스레드가 생성될 때 생기는 공간으로 각 스레드마다 하나씩 할당받는다.
스레드 실행에 대한 기록과 JVM의 명령 주소가 저장된다.
2) JVM Stack
프로그램 실행 과정에서 임의로 할당되고, 소멸되는 데이터를 저장하는 영역.
임시 데이터, 스레드, 메소드 정보와 같은 내용이 저장된다. 메서드 호출마다 각 스택에 정보가 저장된다.
3) Native method stack
자바 바이트 코드가 아닌 실행할 수 있는 기계어로 작성된 프로그램이 들어가 있다.
자바가 아닌 다른 언어로 작성된 프로그램을 위한 공간이다.
4) Method Area
class area, static area이라고도 부른다. 초기화되는 대상을 저장하기 위한 메모리 공간이다.
프로그램 흐름을 구성하는 바이트 코드가 저장된다.
5) Runtime Constant Pool
method area 안에 있는 것으로, 상수 자료형을 저장하여 참조하는 역할을 한다. 중복 참조를 막기 위해 저장하는 영역.
4. 런타임 영역 속 힙 Heap 영역
힙 영역은 객체를 저장하는 가상 메모리 영역이다. 동적으로 할당하여 사용하는 영역이며, 힙 영역에 있는 데이터를 가르키는 참조변수는 스택 영역에 들어가 있다. JVM stack에서는 사용이 끝나면 메모리에서 삭제되지만, Heap에 있는 데이터는 사용이 끝나도 삭제되지 않고 남아 있다. 이 데이터의 삭제를 가비지컬렉터(GC)에서 담당한다.
1) Permanent Generation
객체의 정보와 주소값이 저장된다. JVM에 의해서 사용되며, 동적으로 클래스가 로딩되는 경우 사용한다.
2) New / Young Area
- Eden: 객체가 최초로 생성되는 영역
- Survivor 0/1: Eden에서 참조되는 객체가 저장되는 영역
3) Old Area
New에서 일정시간 참조 되고 있는 객체가 저장된다. 그리고 Eden이 꽉 찼을 경우, 그 메모리 관리를 GC에서 진행한다.
Eden의 값을 Survivor 1에 복사하고, 나머지 값을 삭제한다.
이 방법이 이제는 더 이상 사용하지 않는 인스턴스를 정리하는 Garbage Collection의 역할이다.
JVM 정리
1. JDK에 있는 JVM은 자바 실행을 위한 가상 머신이다.
2. Compiler를 통해서 원시 코드(.java)를 자바 바이트 코드(.class)로 변환한다.
3. 클래스로더를 통해 자바 바이트 코드를 메소드 영역에 저장한다.
4. 자바 바이트 코드를 검증하여 런타임 영역으로 올리면, 실행 엔진에서 기계어로 변환해 실행한다.
5. 프로그램이 실행되면 데이터 별로 각 메모리에 저장되는데, 지역변수나 매개변수처럼 실행되었다가 사라지는 것은 Stack영역에 저장되고, 참조형을 가지는 인스턴스된 객체의 경우는 Heap에 저장된다.
6. Stack에 있는 데이터는 사용이 끝나면 삭제되지만, Heap에 있는 데이터는 바로 삭제되지 않고 GC에서 메모리 정리를 담당한다.
reference
rvrlo, 「[Java/자바] 자바 가상 머신 JVM이란?」, Pale Blue Dot, https://rvrlo.tistory.com/entry/Java%EC%9E%90%EB%B0%94-%EC%9E%90%EB%B0%94-%EA%B0%80%EC%83%81-%EB%A8%B8%EC%8B%A0-JVM%EC%9D%B4%EB%9E%80
제이온, 「[Java] JVM의 클래스 로더란?」, 느리더라도 꾸준하게, https://steady-coding.tistory.com/593
asfirstalways, 「#자바가상머신, JVM(Java Virtual Machine)이란 무엇인가?」, Devlog, https://asfirstalways.tistory.com/158
junghan, 「[JAVA기초] JVM이란?」, junghan.log, https://velog.io/@jungmyeong96/JAVA%EA%B8%B0%EC%B4%88-JVM%EC%9D%B4%EB%9E%80
남궁성, 「Java의 정석」, 도우출판(2016).
'Language > JAVA' 카테고리의 다른 글
[JAVA] 예외 처리(Exception Handling) 하는 이유와 방법 알아보기 (0) | 2025.01.15 |
---|---|
응집도(Conhension)와 결합도(Coupling), 그리고 캡슐화의 중요성 (0) | 2025.01.14 |
객체 지향 5대 원칙 - SOLID 이해하기 (0) | 2025.01.10 |
객체 지향 프로그래밍(Object-Oriented-Programming) 자세히 이해하기 (0) | 2025.01.08 |
[자바/JAVA] 상속과 인터페이스의 관계, 인터페이스 잘 구현하기 (0) | 2025.01.08 |