자바 런타임 환경과 메모리, Java Heap Permgen and MetaSpace

dropKick·2020년 11월 27일
0

Deep Java See

목록 보기
16/21

작년에 공부했더 걸 보다가 런타임 환경의 자바 메모리 구조에 대해서 공부한게 있었는데
힙 사이즈 할당에 관한 글이였음


  • 이 때 단순히 I/O 하면서 자바가 메모리를 운영체제에서 런타임 어떻게 할당 받는가에 대한 궁금증으로 작성했던 글
  • non-direct buffer는 JVM Heap에서 메모리를 할당 받기에 에러 발생

그런 의미로 JVM 내 메모리를 할당하는 Permgen과 MetaSpace의 차이를 알아보려 함

요약

  • 자바는 프로세스가 할당받은 메모리 영역이 아닌 Native Memory 영역이 존재
  • GC, JNI, 메타데이터, Direct-Buffer 등은 Native Memory를 통해 관리
  • 메타데이터는 JDK 8부터 Native Memory의 관리로 변경되었음

JVM Native Memory

그 전에 Native Memory를 알 필요가 있다
Native Memory는

  • Native Code로 시스템 콜을 호출
  • 운영체제가 시스템 콜을 통해 메모리를 애플리케이션에 할당

이 때 프로세스(자바)는 메모리 할당에 관여하지 않는 메모리로 자주 나오는 JNI(Java Native Interface)도 이 곳에 속한다
그리고 자바의 Direct-Buffer도 시스템 콜을 통해 운영체제에게서 직접적으로 메모리를 할당 받는다

Permgen

<----- Java Heap ----->             <--- Native Memory --->
+------+----+----+-----+-----------+--------+--------------+
| Eden | S0 | S1 | Old | Permanent | C Heap | Thread Stack |
+------+----+----+-----+-----------+--------+--------------+
                        <--------->
                       Permanent Heap
S0: Survivor 0
S1: Survivor 1

Java 7까지 존재하던 네이티브 메모리 영역이다
위치를 보면 알겠지만 별도의 펌젠 힙을 통해 관리되던 영역으로 별도의 힙 영역을 설정해주어 관리해야 했고, 이는 생각치않은 메타데이터 영역의 오류를 발생시켰다

자바 내 메타데이터

  • Class Meta Data
  • Method Meta Data
  • Static Object Variable

MetaSpace

<----- Java Heap -----> <--------- Native Memory --------->
+------+----+----+-----+-----------+--------+--------------+
| Eden | S0 | S1 | Old | Metaspace | C Heap | Thread Stack |
+------+----+----+-----+-----------+--------+--------------+

이러한 개발자들의 메모리 영역에 대한 자유를 최대한 보장해주기 위해 펌젠은 JDK 8부터
MetaSpace라는 이름으로 변경되었고 그 이름답게 메타데이터를 저장하는 영역이며 네이티브 메모리에 합쳐지면서 운영체제가 메모리를 동적할당하는 방식으로 변경되었다

또한 메모리의 동적할당으로 이루어지기 때문에 메모리 단편화를 방지하기 위하여 블록 할당방식으로 변경되었으며 메타데이터의 정보는 힙과 네이티브 메모리 두 영역에 모두 할당될 수 있다

결론

필요하다면 필요하고 없다면 없는 정보지만
자바를 사용한다면 적어도 메모리의 어떤 부분에서 문제가 발생할 수 있는지는 구조는 아는 게 좋을 것 같아 공부해봤다

참고

0개의 댓글