JVM 메모리 구조 이해

JVM의 메모리 구조

JVM 메모리는 크게 메서드 영역, 힙(Heap) 영역, 가상 머신 스택(VM Stack), **네이티브 메서드 스택(Native Method Stack)**으로 나뉜다.

1. 메서드(Method) 영역

  • 저장되는 데이터:
    • 클래스 메타데이터(클래스, 인터페이스 정보)
    • 정적 변수
    • 메서드의 바이트코드
    • 런타임 상수 풀(리터럴, 상수)

2. 힙(Heap) 영역

  • 저장되는 데이터:
    • 동적으로 생성된 객체와 배열
    • 참조 타입의 객체 데이터

3. 가상 머신 스택(VM Stack)

  • 저장되는 데이터:
    • 로컬 변수
    • 메서드 호출 정보
    • 연산 스택에서 계산된 중간 값

4. 네이티브 메서드 스택(Native Method Stack)

  • 저장되는 데이터:
    • 네이티브 메서드 호출 정보
    • 네이티브 라이브러리 코드

코드 예시

public class JvmMemoryExample {
    // 메서드 영역에 저장되는 정적 변수
    static int staticVar = 100;

    // 힙 영역에 저장되는 객체 필드
    String instanceVar;

    public JvmMemoryExample(String instanceVar) {
        // 힙 영역에 저장된 객체의 필드를 초기화
        this.instanceVar = instanceVar;
    }

    public void displayVariables() {
        // 가상 머신 스택에 저장되는 로컬 변수
        int localVar = 10;

        // "hello"는 힙 영역의 String Pool에 저장된 리터럴을 참조
        String str = "hello";  

        System.out.println("staticVar: " + staticVar);   // 메서드 영역에 있는 정적 변수
        System.out.println("instanceVar: " + instanceVar);  // 힙 영역에 있는 객체 필드
        System.out.println("localVar: " + localVar);    // 스택에 있는 로컬 변수
        System.out.println("str: " + str);    // 스택에 있는 참조 변수, 힙의 String Pool을 참조
    }

    public static void main(String[] args) {
        // 힙 영역에 객체가 생성되고 스택에 참조 변수가 저장됨
        JvmMemoryExample example = new JvmMemoryExample("JVM 힙 예시");

        // 메서드 호출로 가상 머신 스택에 스택 프레임이 생성됨
        example.displayVariables();
    }
}

설명

메서드 영역

  • staticVar: 정적 변수로 메서드 영역에 저장된다. 클래스가 로드될 때 한 번만 생성되며 모든 인스턴스에서 공유된다.

힙 영역

  • example 객체: new JvmMemoryExample("JVM 힙 예시")를 통해 힙에 저장된다.
  • instanceVar: 객체의 인스턴스 필드로 힙에 저장된다.
  • "hello": 문자열 리터럴로 힙 영역의 String Pool에 저장된다.

가상 머신 스택

  • localVar: 메서드 호출 시 스택 프레임에 저장되는 로컬 변수이다.
  • str: 스택에 저장된 참조 변수이며, 힙의 String Pool에 저장된 문자열 리터럴을 가리킨다.

네이티브 메서드 스택

  • 이 코드에서는 직접적으로 네이티브 메서드를 호출하지 않았지만, 네이티브 메서드를 사용할 경우 JNI를 통해 네이티브 메서드 스택이 사용된다.