본문 바로가기

JAVA

[JAVA8] Native Memory, Metaspace

728x90

============

참고

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/considerations.html

https://dzone.com/articles/java-8-permgen-metaspace

https://brunch.co.kr/@heracul/1

https://blog.voidmainvoid.net/210

============

 

JDK 7과 JDK 8을 구분짓는 요소 중에 하나로 Metaspace가 있다.

Metaspace는 JAVA 8 버전에 소개된 내용으로, JDK 7까지의 Permgen의 역할을 담당하는 요소이다.

Metaspace의 역할은 Permgen의 역할과 크게 다르지 않다.

클레스의 메타데이터를 담는 영역임에는 틀림이 없다.

Permgen의 경우에는 JVM의 관리를 받는 Heap영역에 속한 Native Memory 영역인데 반해,

Metaspace는 OS의 관리를 받는 Native Memory 영역이라는 것에서 차이를 보이는 것이다.

 

Metaspace의 default 값은 몇이고, 최대값은 몇일까?

플랫폼별로, bit 수 별로 다르겠으나, 일반적으로는 default 값은 12MB에서 20MB를 오간다고 한다.

최대값은 운영체제의 bit값 만큼의 크기이다. 만일 64bit의 서버 환경이라면 2^64  bit = 2,097,152 TB이다.

Metaspace의 최대값은 왜 이렇게 클까? 앞서 언급했듯이 OS의 영향을 받는 Native 영역의 Memory라서 그렇다.

-XX:MetaspaceSize=512m 로 선언하는 것은 MetaspaceSize의 초기값을 512m로 설정하는 것이다.

-XX:MaxMetaspaceSize=512m 로 선언하는 것은 MeataspaceSize의 최대값을 512m로 설정하는 것이다.

 

Metaspace의 최대값은 2^64  bit인데 최대값을 지정하는 옵션이 존재한다.

 

OS의 관리를 받다보니 굳이 크기 지정을 할 필요가 없고, 부족하면 부족한 만큼 OS로부터 자원을 가져올텐데

왜 불필요해보이는 최대값 지정 옵션이 존재하는 것일까?

 

그 이유는 Metaspace 영역은 Heap에는 속하지 않지만, Heap과 인접한 주소에 있는 Memory영역이다.

그리고 무한정 Metaspace의 영역이 확장되면, 나중가서는 할당된 메모리가 고갈되어

SWAP 메모리를 건드리는 지경에 빠지게 된다. 최악의 상황은 OS가 뻗어 버리는 불상사가 발생할 수도 있다.

이렇게 되면 모든 애플리케이션의 서비스가 Hang이 걸린 것 처럼 엄청 느리게 된다.

 

그렇다보니 MetaspaceSize의 최대값은 unlimited라고 설명되어 있지만,

반드시 지정하여서 추후 서비스를 원할히 운영되게 만들어야 함을 잊어서는 안 된다.