개발블로그

JVM Memory Model (Runtime Data Areas) 본문

Java

JVM Memory Model (Runtime Data Areas)

개발자수니 2019. 8. 22. 17:32

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

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를 JVM 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입니다.
    • 클래스의 생성자&메소드를 저장하는데, 어플리케이션을 실행한다고 해서 모든 클래스의 클래스&메소드를 로딩하는 것이 아니라 해당 클래스의 인스턴스가 만들어질 때, 그리고 그 클래스의 특정 메소드를 사용할 때마다 저장됩니다.
    • Java 8 이전 버전에서는 Method Area에 Runtime Constants Pool 이 있었는데, Java 8부터는 Heap에서 관리합니다. 이에 대한 내용은 다음 뉴스클리핑에서 살펴볼 예정입니다. 
  • Heap Area 구조 [그림] : 
    • Heap 영역은 GC(Garbage Collection)의 대상이 되기도 하고, 중요한 요소가 많아 그림과 함께 자세히 살펴보겠습니다. 

  • Heap Area :
    • 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은 독립적인 공간을 가집니다. 
    • 원시 변수의 경우, 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에 대해 다음 글에서 살펴보겠습니다. 

 

 

 

 

참조:

http://www.pointsoftware.ch/de/under-the-hood-runtime-data-areas-javas-memory-model/

https://12bme.tistory.com/382
https://slideplayer.com/slide/10540943/

https://d2.naver.com/helloworld/1329

https://mirinae312.github.io/develop/2018/06/04/jvm_memory.html

https://hoonmaro.tistory.com/19

'Java' 카테고리의 다른 글

String Constants Pool  (0) 2019.09.06
Comments