본문 바로가기
Java

Java(JVM) Memory Model(Runtime Data Areas)

by kellis 2020. 10. 21.

JVM은 컴파일된 자바 바이트코드를 실행하는 역할을 합니다. 이때, JVM이 메모리 관리를 어떻게 하는지, 그 구조에 대해 살펴보겠습니다.

JDK 버전이 업그레이드 될 때마다 Java Memory Model도 지속적으로 업그레이드되어 왔습니다. 하지만 전체적인 구조는 유사합니다. 이 글은 JDK8을 기준으로 작성되었습니다.

Java(JVM) 메모리 구조를 살펴보기 앞서 한가지 알아두어야 할 것이 있습니다. JVM 그 자체는 구현체가 아닌 스펙일 뿐이라는 것입니다. JVM Vendor들은 이 스펙을 기반으로 JVM을 구현했고, 구현체의 대표적인 예로 Oracle사의 Hotspot JVM, IBM사의 IBM JVM이 있습니다. Hotspot JVM의 사용률이 압도적으로 높고, 대부분 Hotspot JVM을 사용한다고 할 수 있습니다.

따라서 이 뉴스클리핑에서 살펴보는 메모리 모델도 Hotspot JVM의 메모리 모델입니다. 

먼저, JVM Runtime 환경에 대해 그림으로 살펴보겠습니다. 

  • Class Loader : Java Compiler를 이용해 만들어진 Java Byte Code(.class)를 Runtime Data Areas에 로드하는 역할을 합니다. 여기서 Runtime Data Areas를 Java Memory Model이라 칭합니다. 
  • Execution Engine : Class Loader가 적재한 Runtime Data Areas의 Byte Code를 기계어로 변경해 실행하는 역할을 합니다. 
  • Runtime Data Areas : JVM이 어플리케이션을 실행하기 위해 OS로부터 할당받은 메모리 공간입니다.

Runtime Data Areas는 크게 5개의 영역으로 분리됩니다. 

  • Method Area : 
    • Class Loader가 로딩하는 영역이 바로 Method Area입니다.
    • 클래스의 생성자&메소드를 저장하는데, 애플리케이션을 실행한다고 해서 모든 클래스의 클래스&메서드를 로딩하는 것이 아니라 해당 클래스의 인스턴스가 만들어질 때, 그리고 그 클래스의 특정 메서드를 사용할 때마다 저장됩니다.
    • JDK 8 이전 버전에서는 Method Area에 Runtime Constants Pool 이 있었는데, JDK 8부터는 Heap에서 관리합니다. 이에 대한 내용은 다음 뉴스클리핑에서 살펴볼 예정입니다. 
  • Heap Area : 
    • Heap 영역은 GC(Garbage Collection)의 대상이 됩니다.

    • Heap 영역에는 Array, Object 등 참조 변수가 가리키는 값들이 존재합니다.
    • Heap 영역은 크게 Young Generation과 Old Generation으로 구분됩니다.
    • Young Generation은 Eden, Survivor 0, Survivor 1 영역으로 구분됩니다.
      • Eden은 Object가 처음 할당되는 영역입니다. Eden의 메모리가 가득차면, Eden 영역을 대상으로 Minor GC가 Garbage Collection을 수행합니다. 여전히 살아있는 Object는 Survivor0으로 이동됩니다. 
      • 위 과정을 반복하다가 Survivor0이 가득차면 여전히 참조가 끊기지 않은 Object만 Survivor1로 이동시킵니다. (그럼 다시 Survivor0은 비어있는 상태가 될 것입니다.)
      • Survivor1에서 오래 살아남은 Object는 Old Generation으로 이동됩니다. 
    • 시간이 지나 Old Generation의 메모리도 충분하지 않으면 Major GC가 Garbage Collection을 수행합니다. 
  • Java Stacks :
    • 자료구조에 나오는 Stack으로, 선입후출(First in, Last out) 구조입니다. 
    • 각 쓰레드마다 하나의 Stack이 할당됩니다. 따라서 각 Stack은 독립적인 공간을 가집니다. 
    • 다음 그림에서 하나의 Thread가 실행할 Stack을 볼 수 있습니다. 

    • 원시 변수의 경우, Stack에 저장됩니다. 
    • 참조 변수의 경우, 그 값은 Heap에 저장되며 그 주소 값만 Stack에 저장합니다. 
  • PC Registers :
    • 각 쓰레드마다 하나의 PC Register가 할당됩니다. 
    • 현재 실행중인 JVM 명령 주소를 가지고 있습니다. Java Byte Code(.class)는 Byte Code 명령들이 나열된 형태를 띠게 됩니다. 각 스레드가 이 명령들을 차례로 수행하는데, 수행하고 있는 위치를 저장하기 위한 영역입니다. 
  • Native Method Stacks : Java 외의 언어로 작성된 코드를 위한 Stack 영역입니다. 각 언어별로 Stack이 할당됩니다. 

 

Method Area영역에 대한 설명에서 잠깐 언급했는데, Runtime Constants Pool이 Java8부터 Heap 영역으로 이동하게 되었습니다. 그렇다면 Runtime Constants Pool이 무엇인지, 왜 이동하게 되었는지, 그리고 이와 관련해 Java Runtime Option에 대해 다음 글에서 살펴보겠습니다. 

 

 

 

 

[references]

RUNTIME DATA AREAS – JAVA’S MEMORY MODEL

By Manish Shrotriya CSE300 2014MS Java Memory Model From

 

By Manish Shrotriya CSE MS Java Memory Model From - ppt download

By Manish Shrotriya CSE MS Heap and Method area From

slideplayer.com

Java Garbage Collection

 

 

 

댓글