..

JVM Memory Structure: Stack, Heap, Method Area

TOC


  1. Overview
  2. 메모리 구조
  3. Stack
  4. Heap
  5. Method Area
  6. Conclusion
  7. Next Step

Overview


최근에 class 파일이 JVM 안에서 어떻게 사용되는지 다뤘다.

이번 글에서는 실행 중 JVM이 쓰는 메모리 영역에 대한 내용을 다룬다.

메모리 구조


JVM 메모리는 보통 크게 Stack, Heap, Method Area로 나눠서 이해하면 된다.

block-beta
  columns 6
  JVM["JVM Runtime Memory"]:6
  Stack["Stack"]:2
  Heap["Heap"]:2
  MethodArea["Method Area"]:2
  Method["Method"]:1
  LocalVariable["LocalVariable"]:1
  Object["Object"]:1
  Array["Array"]:1
  Metadata["Metadata"]:1
  Static["Static"]:1

이 그림은 각 영역이 어디에 속하는지를 보여주는 최소한의 지도다.

  • Stack: 메서드호출(frame), 지역변수
  • Heap: 인스턴스, 배열
  • Method Area: 클래스메타데이터, static 정보

Stack


스택에는 메서드 호출마다 frame이 쌓인다. frame은 호출 시 push되고, 메서드가 끝나면 pop된다. frame 안에는 지역 변수와 연산용 데이터가 들어간다.

public class StackDemo {
    public static void main(String[] args) {
        int count = 3;
        print(count);
    }

    static void print(int value) {
        System.out.println(value);
    }
}

countvalue 같은 지역 변수는 스택 쪽에서 다룬다. 메서드가 끝나면 frame도 같이 사라진다.

before

  • call main method -> push
  • call a method -> push
block-beta
  columns 1
  Stack["Stack"]
  MainFrame["main frame"]
  MethodFrame["method frame"]

after

  • end a method -> pop
  • end main method -> pop
block-beta
  columns 1
  Stack["Stack"]
  MainFrame["main frame"]

이런 식으로 메서드가 호출되면 frame이 push되어 stack에 쌓이고, 메서드가 종료되면 가장 위 frame이 pop되면서 사라진다. 즉, 스택은 위로 쌓이고 위에서 빠지는 구조다.

Heap


public class HeapDemo {
    public static void main(String[] args) {
        Person person = new Person("kim");
    }
}

class Person {
    String name;
    Person(String name) {
        this.name = name;
    }
}

person 변수는 참조고, 실제 Person 인스턴스는 heap에 있다.

flowchart LR
  subgraph STACK["Stack"]
    direction TB
    REF["person reference"]
  end

  subgraph HEAP["Heap"]
    direction TB
    OBJ["Person instance"]
    FIELD["name: kim"]
    OBJ --> FIELD
  end

  REF -->|points to| OBJ

Heap에는 "Person" 인스턴스가 있고, Stack에는 그 인스턴스를 가리키는 참조(reference)가 들어있다.

Method Area


클래스 정보static 관련 정보는 method area 쪽으로 생각하면 된다.

예를 들면 메타데이터(클래스 이름, 메서드 정보)와 static field로 구성된다.

block-beta
  columns 2 
  MethodArea["Method Area"]:2
  Metadata["Metadata"]:1
  Static["Static"]:1

즉, 여기에는 인스턴스 자체보다 클래스의 뼈대와 static 관련 정보가 들어간다고 보면 된다.

Conclusion


아주 단순하게 정리하면 이렇다.

  • Stack: 메서드 호출과 지역 변수
  • Heap: 인스턴스
  • Method Area: 클래스와 static 정보

Next Step


다음 아티클에서는 Java 객체 생성과 메모리 배치: new, reference, object header를 본다. new가 인스턴스를 어떻게 만들고, 참조가 무엇을 가리키는지 이어서 보자.