이번 글에서는 JVM에서 어떤 일이 일어나는지 Runtime Data Area를 중심으로 살펴보고자 한다.
JVM (자바 가상 머신)
JVM이란 스택 기반의 가상 머신으로 자바 애플리케이션이 OS에 구애받지 않고 실행될 수 있도록 환경을 제공하고, 시스템 메모리를 관리하는 역할을 한다.

- 클래스 로더(class loader) : 클래스 파일들을 엮어서 JVM이 OS로부터 할당받은 메모리 영역인 Runtime Data Area에 적재하는 역할을 한다. 클래스에 대한 정보가 Method Area에 저장된다.
- 실행 엔진(execution engine): 클래스 로더에 의해 메모리에 적재된 클래스(바이트 코드)들을 Interpreter가기계어로 변경해 명령어 단위로 실행하는 역할을 한다.
- 가비지 컬렉터(garbage collector): Heap 영역에 생성된 객체들 중 더이상 참조되지 않는 객체들을 탐색 후 제거하는 역할을 한다. GC가 수행되는 동안 GC를 수행하는 스레드가 아닌 다른 모든 스레드는 일시정지된다.
- Runtime Data Area: 프로그램 수행을 위해 OS로부터 할당받은 메모리 공간이다. 모든 스레드가 공유하는Heap,Method영역과 개별 스레드에서 관리하는PC Register,JVM Stack,Native Method Stack영역으로 구성되어 있다.
자바 애플리케이션의 실행 과정
- 프로그램이 실행되면 JVM은 OS로부터 메모리를 할당받는다.
- 자바 컴파일러(javac)가 자바 소스(.java)를 읽어 자바 바이트 코드(.class)로 변환시킨다.
- 바이트 코드를 JVM의 클래스 로더(class loader)에 전달한다.
- JVM은 클래스 로더를 통해 class 파일들을 JVM 메모리에 로드한다.
- 로딩된 class 파일들은 실행 엔진을 통해 운영체제에 맞는 기계어로 해석된다.
- 해석된 바이트코드는 Runtime Data Area에 배치되어 실질적인 수행이 이루어지게 된다.
Runtime Data Area
Runtime Data Area는 JVM이 사용하는 메모리 공간이라고 생각하면 된다. 다음과 같은 구조로 이루어져 있다.

Method Area
클래스 파일 안에는 클래스 안에 어떤 필드(field)가 몇 개, 무슨 타입으로 선언되어 있는지, 메서드(method)는 몇 개고 이름이 뭔지,
그리고 바이트코드(bytecode)까지 포함해서 모든 정보가 들어있다.
이러한 클래스 파일에 대한 정보는 클래스 로더에 의해 Method Area에 올라가게 된다.
그 외에도 static 변수, 인터페이스 등이 저장된다.
Constant Pool은 클래스 내에 사용되는 상수(constant)들을 담은 테이블이라고 생각하면 된다.
메인 메서드를 실행하면서, JVM은 Constant Pool에 대한 포인터를 유지하여 언제든 직접 참조할 수 있도록 한다.
Heap
Heap은 런타임에 생성되는 모든 객체들이 저장되는 곳으로, new 키워드로 생성된 객체와 배열의 인스턴스가 저장된다.
가비지 컬렉터는 이 Heap 영역에서 동작하여 메모리를 확보한다.
Method Area와 Heap은 모든 스레드 (thread)가 공유하는 영역이다. 따라서 멀티스레드 프로그래밍 시 동기화(synchronization)에 주의해야 하는 영역이다.
JVM Stack
메서드를 실행하기 위한 정보들이 저장되는 공간으로 지역 변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값이 생성된다.

JVM Stack 내부에는 프레임(Frame)이라는 자료구조가 들어가있는데,
이 프레임은 메서드가 호출될 때마다 새로 생기고(push)
메서드가 종료되거나 예외가 발생하면 스택에서 사라진다(pop)
그렇다면 프레임 안에는 어떤 데이터가 담겨있을까?

프레임은 다음과 같이 3가지 구성 요소를 갖는다.
- Constant Pool reference (현재 클래스의 Constant Pool에 대한 참조)
- Local Variables Array (지역 변수 배열)
- Operand Stack (메서드 내 연산을 위한 작업 공간)
각 요소에 대해 잘 정리된 글을 첨부한다..!
JVM stack과 frame
johngrib.github.io
PC Register
PC Registers는 현재 스레드가 실행되고 있는 부분의 주소와 명령어를 저장하는 영역이다.
멀티스레드 환경에서 한 스레드가 작업 하다가 다른 thread로 CPU 점유를 넘겨주고 다시 돌아왔을 때
이전에 어떤 명령을 수행하고 있었는지 기억하기 위해서 존재한다.
Native Method Stack
자바 외 언어(C/C++ 등)로 작성된 코드를 위한 메모리 영역이다. JNI를 통해 사용된다.
이 세 개 영역(JVM Stack, PC Register, Native Method Stack)은 스레드가 생성될 때마다 같이 생성이 되고, 다른 스레드가 침범할 수 없는 영역이다.
하나의 메서드 안에서 지역 변수의 동시성(Concurrency) 문제를 고려하지 않아도 되는 이유가 바로 이것이다.
참고 자료
'Java' 카테고리의 다른 글
| 동시성 이슈와 자바의 동시성 제어 (락 기반 & 락 프리) (0) | 2024.08.12 |
|---|