개발/Java

JVM String Constant Pool

728x90

JVM의 Heap메모리의 Permenent 영역에 존재한다.

 

자바 7에서의 힙에서는

  • PerGen에 있는 클래스의 인스턴스 저장
  • -Xms(min), -Xmx(max로 사이즈 조정

 

PermGen 

  • 클래스와 메소드의 메타데이터 저장
  • 상수풀 정보
  • JVM, JIT 관련 데이터
  • -XX:PermSize(min), -XX:MaxPermSize(max)로 사이즈 조정

 

Perm 영역은 보통 Class의 Meta 정보나,  메소드의 메타 정보, 스태틱 변수와 상수 정보들이 저장되는 공간으로 흔히 메타데이터 저장 영역이라고도 한다.

하지만 자바 8에서는 Native 영역으로 이동하여 Metaspace 영역으로 변경되었다.

 

 

HotSpotVM 기준 자바7, 자바8의 차이

 

자바8 : 메타스페이스 영역

자바 8에부터는 자바 7의 Perm 영역이 삭제되고 Native 영역으로 이동해서 MetaSpace 영역으로 변경됨.

다만 기존 Perm에 존재하는 Static Object는 Heap 영역으로 옮겨져 GC의 대상이 될 수 있도록 변경됨.

Perm은 JVM에 의해 크기가 강제되던 영역임.

 

 Runtime Data Area를 보면 현재 이와 같은 모습을 띄고 있다.

 

왜 Perm이 삭제되고, Metaspace 영역이 추가된 것일까?

 

Metaspace 영역은 Heap이 아닌, Native 메모리 영역으로 취급하게 된다.

OS 레벨에서 자동으로 관리하게 됨

옵션을 통해 Metaspace의 크기를 줄일 수 도 있음

 

Metaspace가 Native 영역을 이용함으로 영역 확보의 상한을 크게 의식할 필요가 줄어듦

Perm 영역크기로 인해 발생하는 OOM의 빈도가 줄어드는 효과

What's New in JDK8에 HotSport 항목에 이와 같은 문장을 찾을 수 있다.

 

 

  Java7 Java8
Class 메타데이터 저장 저장
Method 메타 데이터 저장 저장
Static Object 변수, 상수 저장 Heap 영역으로 이동
메모리 튜닝 Heap, Perm 영역 튜닝 Heap 튜닝, Native는 OS가 동적 조정
메모리 옵션 -XX:PermSize
-XX:MaxPermSize
-XX:MetaspaceSize
-Xx:MaxMetaspaceSize

 

 

JEP 122에서는 아래와 같이 기술하고 있다.

 

현재 Hotspot의 클래스 메타 데이터, interned String, class static 변수들은 Java heap의 permanent generation에 저장됩니다. permanent generation은 Hotspot이 관리하며, 앞에서 말한 것들을 모두 저장하므로 반드시 충분한 공간을 갖고 있어야 합니다. 클래스 메타 데이터와 static 변수들은 클래스가 로드될 때 permanent generation에 할당되고, 클래스가 언로드될 때 gc 처리됩니다. interned String은 permanent generation의 gc가 발생할 때 같이 수집됩니다.

 

구현 제안서에 따르면 클래스 메타 데이터는 네이티브 메모리에 할당하고, interned String와 클래스 statics는 Java heap으로 이동합니다. Hotspot은 클래스 메타 데이터에 대한 네이티브 메모리를 명시적으로 할당하고 해제할 것입니다. 새 클래스 메타 데이터의 할당은 네이티브 메모리의 사용 가능한 양에 의해 제한되며, 커맨드 라인을 통해 설정된 -XX:MaxPermSize 값으로 고정되지 않습니다.

 

네이티브 메모리에서의 클래스 메타 데이터 할당은, 여러 클래스 메타 데이터가 잘 들어가도록 충분한 크기의 여러 블록을 만들어 작업합니다. 각 블록은 클래스 로더와 연결되며 해당 클래스 로더가 로드한 모든 클래스 메타 데이터는 해당 클래스 로더의 블록에서 Hotspot에 의해 할당됩니다. 필요에 따라 클래스 로더에 추가 블록이 할당되기도 합니다. 블록 크기는 애플리케이션의 동작에 따라 다릅니다. 블록의 사이즈는 내부 및 외부 조각화(fragmentation)를 제한하기 위해 선택됩니다. 클래스 로더가 죽을 때 클래스 로더와 연관된 모든 블록을 해제하여 클래스 메타 데이터에 대한 공간을 확보합니다. 클래스 메타 데이터는 클래스의 수명 동안 이동하지 않습니다.

 

 

 

더 알아보기

 

Runtime Constant Pool

클래스 파일 constant_pool 테이블에 해당하는 영역

클래스와 인터페이스 상수, 메소드와 필드에 대한 모든 레퍼런스를 저장한다.

JVM은 런타임 상수 풀을 통해 해당 메소드나 필드의 실제 메모리 상 주소를 찾아 참조한다.

 

출처 :

https://johngrib.github.io/wiki/java8-why-permgen-removed/

'개발 > Java' 카테고리의 다른 글

자바 volatile 이란?  (0) 2021.05.17
BigInteger, BigDecimal 클래스  (0) 2021.05.17
Spliterator란  (1) 2021.05.17
non-reifiable 타입이란  (0) 2021.05.17
Java Datagram 관련 클래스  (0) 2021.05.17