2025-03-27
JVM 메모리 구조와 클래스 로딩 (Constant Pool과 intern())
JVMJava메모리Constant Poolintern
JVM 메모리 구조와 클래스 로딩 (Constant Pool과 intern())
Runtime Data Area
JVM이 실행 시 메모리를 여러 영역으로 할당합니다.
1. Method Area
클래스 로딩 시 클래스 메타정보, static 변수, constant pool 복사본이 저장됩니다. Runtime Constant Pool이 이 영역의 일부로 포함됩니다. Java 8 이후부터 Metaspace(네이티브 메모리)에 저장됩니다.
public class StaticExample {
static String val = "loaded";
static {
System.out.println("StaticExample loaded!");
}
}
public class LoadTest {
public static void main(String[] args) throws Exception {
Class.forName("StaticExample"); // Method Area에 로딩됨
}
}
// javac StaticExample.java LoadTest.java
// java LoadTest
/**
* 출력결과
* Before loading
* StaticExample loaded!
* After loading
*/2. Heap
new로 생성된 모든 객체는 Heap에 저장됩니다. intern된 문자열도 Java 7부터 Heap에 존재합니다.
String heapString = new String("apple"); // Heap에 생성3. Stack
각 스레드는 자체 JVM Stack을 유지합니다. 메서드가 호출되면 프레임이 생성되고 LIFO 순서로 제거됩니다. 지역 변수와 매개변수가 저장됩니다.
public void add(int a, int b) {
int sum = a + b; // Stack에 저장됨
}4. Program Counter (PC Register)
현재 실행 중인 JVM 명령어의 위치를 추적합니다. 스레드당 하나씩 존재합니다.
5. Native Method Stack
네이티브 코드 실행(C/C++ via JNI)을 위한 영역입니다.
Constant Pool & Runtime Constant Pool
Constant Pool
컴파일된 .class 파일 내에 존재하며, 컴파일 타임에 생성됩니다. 문자열 리터럴, 클래스 이름, 메서드 이름, 필드 이름, 타입 등의 상수 정보를 저장합니다. 각 클래스마다 하나씩 존재하며, JVM은 런타임 시 메서드 호출과 필드 접근에 이 정보를 사용합니다.
String s = "Hello";
// "Hello"는 컴파일 타임에 상수 풀에 저장됨Runtime Constant Pool
JVM이 클래스를 메모리에 로드할 때 생성되는 상수 풀의 런타임 버전입니다. 클래스 로더가 .class 파일을 로딩할 때 상수 풀 정보를 복사하며, 동적으로 추가된 상수와 참조도 포함할 수 있습니다.
String a = "Hi";
String b = "Hi";
System.out.println(a == b); // true
// "Hi"는 상수 풀에 저장되고, a, b는 같은 객체를 참조함정리
- Constant Pool은 .class 파일에 존재하고, Runtime Constant Pool이 Method Area에서 이를 참조
- Heap은 객체 저장소, Stack은 실행 컨텍스트 유지
intern()은 문자열을 Heap 내 intern pool에 연결