바이트 코드(=클래스 파일)을 ClassLoader를 이용해 메모리(Runtime data area)에 실행 가능한 상태로 적재한다.

구성요소

Method Area, Heap,PC Registers, JVM Stacks, Native Method Stacks으로 구성된다.
Heap과 Method Area는 각각의 스레드가 메모리를 공유한다.
Method Area
클래스에 대한 정보가 올라오는 영역으로 모든 쓰레드가 공유함. Static영역
프로그램 실행 중 클래스나 인터페이스를 사용하게 되면 JVM은 ClassLoader에게 요청하여 클래스와 인터페이스의 메타데이터를 Method Area에 저장한다.
클래스에 대한 정보가 이 영역에 존재하기 때문에 인스턴스를 생성하기 위해서는 Method Area를 참조해야 하며, 따라서 모든 쓰레드가 이 영역을 공유하게 된다.
=> 인스턴스란, MethodArea에 저장된 클래스의 필드 정보나 메소드 정보등을 활용해 Heap 메모리에 객체를 하나 저장한것.
Method Area에 저장되는 Metadata 구조.
Type Information : 클래스와 인터페이스의 정보
- Type의 이름(Symbolic reference) : 패키지 이름을 포함한 클래스의 이름
- Type의 종류 : Class 인지 interface인지
- Type의 제어자 : 접근제어자(public, private 등) 및 기타 제어자(abstract, final 등)
- 연관된 Interface의 정보 : Class에 사용된 Interface의 정보(= 인터페이스의 구현체 리스트)
Runtime Constant Pool : Type의 상수 정보를 저장하는 Pool. 인덱스를 통해 접근이 가능
- 클래스와 인터페이스 상수, 메소드와 필드에 대한 모든 Reference를 저장( = 해당 클래스가 참조하는 클래스들의 이름, 변수들의 초기값등의 데이터)
- JVM에서는 해당 메소드와 필드의 실제 메모리상의 주소를 찾기 위해 참조함
- Method Area에 클래스의 정보가 올라오면 Constant Pool에 대한 포인터를 하나 생성해 언제든지 클래스 내의 상수에 대해 접근이 가능하도록 한다.
@클래스나 인터페이스를 생성할 때, 이 constant pool을 메모리에 다 담을 수 없게 되면 OutOfMemory에러가 발생함.
@ Method Table은 메소드의 이름과 시그니처를 키로하고, 바이트코드를 가리키는 포인터를 밸류로 하는 데이터 구조이다.
=> JVM은 Method Area에서 constant pool이 가지고 있는 reference를 통해 원하는 객체를 빈번하게 검색해야 하는데, 속도를 향상시키기 위해서 Method Table을 사용한다. Method Table은 부모 클래스의 이름과 그 포인터도 모두 가지고 있기 때문에, 상위 클래스를 거슬러 올라가는 resolution이 한 번의 lookup으로 가능해진다
Field Information : 인스턴스 변수의 정보를 저장한다
- Type명 : 인스턴스 변수의 타입(= 클래스나 인터페이스에서 선언된 모든 필드 정보, 필드가 선언된 순서대로 기록된다.)
- Type의 제어자 : 접근제어자(public, private,protected,static 등) 및 기타 제어자(abstract, final 등)
Method Infeomation : 메소드의 모든 정보를 저장한다
- Method 이름
- Method return type
- Method parameter수와 각 parameter의 type정보
- 필요한 메소드에 대한 정보들
@ 메소드가 native나 추상 메소드가 아니라면 여기(method information)에 메소드의 바이트 코드, 메소드 Stack Frame의 Operand Stack과 Local Variabel Section의 크기, Exception Table을 포함한다.
Class Variable : static 키워드로 선언된 변수를 저장한다
- 클래스에서 static으로 선언된 변수들.
- 클래스를 사용하기 전부터 미리 method area에 메모리를 할당 받는다. 단, final로 선언하면 상수로 취급되어 constant pool에 Literal Constant로 저장된다.
Reference to ClassLoader & class Class
- 특정 클래스를 로드한 클래스로더의 정보를 관리
- Class object와 서로 양방향 접근을 하기 대문에 Class Object에 대한 참조 주소 값을 가진다
Heap
- JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 영역( = 프로그램이 실행되며 동적으로 생성된 인스턴스가 저장된다.)
- new 연산자로 생성된 객체 또는 인스턴스와 배열을 저장
- 힙 영역에서 생성된 객체와 배열은 스택 영역의 변수나 다른 객체의 필드에서 참조
- 참조하는 변수나 필드가 없다면 의미 없는 객체가 되어 GC의 대상이 된다 (효율적인 메모리 영역의 관리를 위한것)


Young(New) Generation : Eden 영역과 Survivor영역으로 구성
- Eden 영역
- Object(객체)가 최초로 Heap에 할당되는 장소
- new 키워드를 통해 새로운 인스턴스가 생성되어 저장된다.
- 만일 Eden 영역이 가득 찼다면, Object의 참조 여부를 파악하고 LiveObject는 Suvrvior 영역으로 넘긴다
- 모든 LiveObject가 Survivor영역으로 넘어간다면 Eden영역을 청소 (참조가 사라진 GarbageObject)
- Survivor 영역
- Survivor0과 Survivor1로 구성
- Eden영역에 살아남은 Object들이 잠시 머무르는 곳이며 LiveObject들은 하나의 Survivor 영역만 사용
- 이러한 전반적인 과정을 Minor GC
Tenured(Old) Generation
- Survivor1 또는 Survivor2 영역(= Young Generation영역 )을 왔다 갔다 하는 과정에서 끝까지 살아남은 객체만이 Old 영역으로 이동
- Old영역에 할당된 메모리가 허용치를 넘게 되면, Old영역에 있는 모든 인스턴스들을 검사하여 참조되지 않는 인스턴스를 한꺼번에 삭제한다(Major GC)
- Major GC가 발생하면 GC를 실행하는 쓰레드를 제외한 모든 쓰레드가 작업을 중지한다(Stop-the-World)
Permanent Generation(Metaspace)
- ClassLoader에 의해 동적으로 로딩된 클래스의 메타데이터가 저장되는 영역(= Class의 Meta정보나 Method의 Meta정보, Static변수와 상수 정보들이 저장되는 공간, 흔히 메타데이터 저장 영역 )
- Java 8 이후 Metaspace로 대체되어 Heap영역에서 제외되었다

헷갈리는 부분.
Heap의 구성요소를 찾아보면 young, old, perm이 나오는데 Permanent Generation은 Heap의 구성요소가 맞냐
- 아니라고 한다 - stackoverflow.com/questions/41358895/permgen-is-part-of-heap-or-not
- 그렇다면, 위에서 설명한 Heap의 구성요소에 속하는 PermGen 설명은 틀린 것..

Java8부터 HotspotJVM의 Permanent Generation이 Metaspace로 바뀐 것은 잘 알려져있다.
Permenant Generation(이하 PG)은 Heap 메모리에 속했고 MetaSpace는 그렇지 않지만, 둘 다 GC의 대상이(었)다.
PG는 사이즈가 동적으로 가변적이지 않아서 부족해지면 OutOfMemoryError: PermGen 이라는 에러가 발생했던 반면, MetaSpace는 네이티브 메모리로서 그 크기가 -XX:MetaspaceSize 내에서 동적으로 가변적으로 변할 수 있어 더 이상 OutOfMemoryError: PermGen 과 같은 에러는 발생하지 않게 되었다.
참고로 -XX:MetaspaceSize 옵션의 디폴트 값은 unlimited이다.

Heap에 관련된 내용이 너무 많아서 이후 다른 포스팅에 정리해보도록 하겠다.
PC Register, JVM Stack, Native Method Stack은 각 스레드 별로 존재한다.
각 쓰레드마다 서로 다른 메모리가 할당된다.
Stack
지역변수, 메소드의 매개변수, 리턴값 등 임시적으로 사용되는 값들이 저장되는 영역으로 PC Register, Native Method Stack과 함께 쓰레드가 생성될 때마다 할당된다.
간단한 동작 과정
프로그램 실행 시 메소드가 실행되면 JVM은 Stack영역에 해당 메소드의 frame을 push하고, 데이터를 임시적으로 저장한다. 메소드가 종료되면 Stack에서 해당 메소드의 frame을 pop한다.

Stack의 기본 자료구조인 Frame은 아래 세 가지 요소로 구성되어있다.
Constant Pool Reference : Method Area의 Runtime Constant Pool에 대한 참조
- 메소드가 속한 클래스의 상수를 사용하기 위해 Runtime Constant Pool에 대한 참조값을 가진다
Local Variables Array : 매소드 내의 지역변수를 담고있는 배열
- 첫번째 인덱스에는 현재 인스턴스에 대한 참조값을 저장(this)
- 두번째 인덱스부터 매개변수 -> 지역변수 순으로 값을 저장
Operand Stack : 피연산값과 계산과정에서 생기는 중간값을 저장
- JVM은 Stack기반으로 연산을 수행함
- 따라서 연산에 필요한 operand가 모두 Stack에 저장되어있기 때문에 Byte Code는 일반적인 어셈블리어와 달리 operand를 지정하지 않아도 연산이 가능하다
- 다른 어셈블리어와 달리 연산에 레지스터를 쓰지 않은 이유는 각 디바이스마다 레지스터의 수가 달라 그 수를 가정할 수 없기 때문에 하드웨어의 관여를 최소화하기 위해 JVM에서는 연산과정이 복잡하더라도 Stack을 사용한다
만약 쓰레드가 사용할 수 있는 스택의 크기를 넘기게 되면 StackOverflowError 가 발생한다. 또한 스택을 동적으로 확장할 때 확장할 메모리가 부족하거나 새로운 쓰레드 생성 시 스택에 할당할 메모리가 부족하면 OutOfMemoryError 가 발생한다.
PC Register
Stack, Native Method Stack과 함께 쓰레드가 생성될 때 각 쓰레드마다 생기는 공간으로, 현재 수행중인 JVM의 명령어 주소를 저장한다.
JVM은 Stack-Base방식으로 작동하기 때문에 CPU에 직접 Instruction을 수행하지 않고, Stack에서 Operand를 뽑아내어 별도의 메모리 공간에 저장한 다음 연산을 진행하는데, 이때 사용되는 메모리공간이 PC Register이다.
PC Register에는 멀티 쓰레드 프로그래밍 환경에서 한 쓰레드가 작업을 하다가 다른 쓰레드로 CPU자원을 넘겨주고 다시 받았을 때, 이어서 작업을 하기 위해 현재 실행중인 명령어의 주소를 기록한다.
만약 쓰레드가 JVM Instruction을 수행중이라면 Instruction의 주소를 가지고 있지만, Native Method를 수행중이라면 PC Register는 Undefined상태로 남아있고, 이에 대한 처리는 Native Method Stack에서 담당한다.
Native Method Stack
Native 언어(C/C++, 어셈블리)로 작성된 코드를 실행하기 위한 메모리 영역
- 자바 이외의 언어가 JVM에서 동작하기 위해 할당한 메모리 영역으로, 일반적으로 C스택을 사용한다
- 쓰레드에서 java메소드가 아닌 Native방식을 사용하는 메소드를 실행하면 이 곳에 해당 메소드에 대한 정보를 저장한다
- JNI(Java Native Interface)를 통해 표준에 가까운 방식으로 구현이 가능하다.
https://kkang-joo.tistory.com/18
[JAVA] JVM 메모리 구조, 데이터 영역 ( Runtime Data Areas)
JVM의 구성요소 중, 데이터 영역에 대한 설명으로 아래의 내용들에 대해서 다루어 보도록 하겠다 Runtime Data Areas란 Runtime Data Areas의 구성 요소 스레드 별로 존재 PC Register JVM Stack Native Method Stack 스
kkang-joo.tistory.com
https://velog.io/@impala/JAVA-JVM-Runtime-Data-Area
[JAVA] JVM - Runtime Data Area
JVM의 메모리영역인 Runtime Data Area에 대해 알아보고 각 영역별 특징과 역할을 이해한다
velog.io
https://woojoovove.tistory.com/36
Method Area 정의와 구성
Method Area란?Method Area는 모든 스레드들이 공유하는 메모리 영역으로 JVM이 기동될 때 JVM 당 하나씩 생성된다. Garbage Collection(이하 GC)의 대상이 되는 영역으로, 클래스로더가 로드한 클래스 파일로
woojoovove.tistory.com
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5
Chapter 2. The Structure of the Java Virtual Machine
Conditional branch: ifeq, ifne, iflt, ifle, ifgt, ifge, ifnull, ifnonnull, if_icmpeq, if_icmpne, if_icmplt, if_icmple, if_icmpgt if_icmpge, if_acmpeq, if_acmpne.
docs.oracle.com
https://www.artima.com/insidejvm/ed2/jvm5.html
Java Virtual Machine's Internal Architecture
Chapter 5 of Inside the Java Virtual Machine The Java Virtual Machine by Bill Venners << Page 5 of 13 >> Advertisement The Method Area Inside a Java virtual machine instance, information about loaded types is stored in a logical area of memory called
www.artima.com
https://www.youtube.com/watch?v=OAZL0emZTWs
간단히 참고용으로 보면 좋음.
공부용으로 작성한 글입니다. 문제시 비공개처리하겠습니다.
'언어 > java' 카테고리의 다른 글
| 객체의 메모리 레이아웃과 Heap(JVM) (1) | 2026.01.23 |
|---|---|
| JVM의 Class Loader(클래스 로더)란? (0) | 2026.01.19 |
| JVM이란? 메모리 구조! (0) | 2026.01.14 |