개발놀이터

자바의 Metaspace 본문

Java

자바의 Metaspace

마늘냄새폴폴 2022. 7. 28. 09:23

Metaspace

Java8부터 JVM의 메모리 영역 중 PermGen이라 부르는 Permanent Generation 메모리 영역이 사라지고 Metaspace 영역이 생겼다.

 

Metaspace는 간단히 말해 Java의 클래스 로더가 로드한 클래스들의 메타데이터가 저장되는 공간이다. 

 

여기서 잠깐! 메타데이터가 뭘까?

 

MetaData란?

흔히 컴퓨터 사이언스 (CS)에서 말하는 메타데이터는 이렇게 정의한다. "어떤 목적을 가지고 만들어진 데이터" 

 

디지털 카메라로 예를 들자면, 디지털 카메라로 사진을 찍어 기록할 때마다 카메라 자체의 정보와 촬영 당시의 시간, 노출도, 플래시 사용여부, 해상도, 사진크기 등의 사진 정보를 화상 데이터와 같이 저장하게 되어있다. 이러한 데이터를 분석하여 이용하면 그 뒤에 사진을 적절하게 정리하거나 다시 가공할 때에 아주 유용하게 쓸 수 있는 정보가 된다. GPS 기능을 사용하여 위치 정보까지 사진의 메타데이터에 입력할 수도 있는데, 이를 이용하면 사진이 어디에 촬영되었는지 쉽게 알 수 있고, 이로써 다시 다른 지역 정보를 검색하거나 같은 지역에서 찍은 다른 사진을 검색하게 하는 검색성을 향상시킬 수 있다.

 

메타데이터에 대한 추상적인 얘기는 끝났는데 그래서 자바에서 메타 데이터가 뭔데? 뭐가 메타스페이스에 저장되는데? 라고 묻는다면 자바에서 가장 대표적인 메타데이터가 바로 어노테이션이다. 

 

자바의 입장에서 메타데이터란 애플리케이션이 처리해야 할 데이터가 아닌, 컴파일 과정과 실행 과정에서 코드를 어떻게 컴파일하고 처리할 것인지를 알려주는 데이터이다. 

 

 

 

이렇게 메타데이터에 대해 알아봤고 다시 본문으로 돌아오자면

 

Java7까지의 Permgen과 Java8 이후 Metaspace의 가장 큰 차이는 Metaspace는 Permgen과 달리 Heap영역이 아닌 NativeMemory영역에 위치한다는 점이다. 아래의 그림을 참고하자.

 

그럼 Native Memory에 대해서도 알아봐야하지 않을까?

 

Native Memory

Native Memory는 Heap 영역 바깥인 Off-Heap 공간을 의미하는 것으로 쉽게 얘기해서 시스템의 기본 메모리라고 생각하면 된다. Java 애플리케이션은 크게 위의 Heap과 Off-Heap 두 공간을 활용하여 동작한다.

 

따라서 애플리케이션을 배포할 때 메모리를 몇 GB를 할당해야 하는지 결정하기 위해서는 단순히 Xmx(Heap 메모리 최대치를 결정하는 Java 옵션) 값만 생각하면 OOME에 빠지기 쉽다. 실제로는 Xmx에 MaxMetaspace값을 더하고, 추가로 프로그램에서 NIO를 사용해 Native Memory를 직접 할당받는 로직을 고려해서 Heap + Native Memory 사용 총량으로 할당해야 비교적 정확하다.

 

 

 

다시 본문으로 돌아와서

 

따라서 "java.lang.OutOfMemoryError: PermGen space"와 같은 종류의 OOM은 더 이상 마주칠 일이 없으며 -Xmx 옵션에 의해 설정되는 Heap 사이즈가 아닌 Host 운영 시스템에 의해서 그 사이즈가 제약된다.

 

그런데 그 말은 즉, 만약 애플리케이션이 많은 클래스를 로드한다면 단순히 애플리케이션의 OOM이 아니라 전체 서버를 다운시킬 수도 있다는 얘기가 된다. 따라서 적절한 flag값 (-XX:MaxMetaspaceSize 등)을 설정해주는 것이 필요할 수 있다.

 

Metaspace는 언제 할당되고 릴리즈 될까? 할당은 클래스가 로드되고 런타임이 JVM에 준비될 때 클래스의 메타데이터 저장을 위해 Metaspace가 클래스로더에 의해 할당된다. 즉 런타임 시점에 할당된다. 릴리즈는 클래스로더가 업로드 될 때만 일어난다.

 

Metaspace의 사이즈를 지정하는 파라미터들 중 대표적으로 MaxMetaspaceSize, CompressedClassSpaceSize가 있다. 

  • -XX:MetaspaceSize : 초기 / 최소 Metaspace 사이즈
  • -XX:MaxMetaspaceSize : 최대 Metaspace 사이즈
  • -XX:CompressedClassSpaceSize : Metaspace의 중요한 부분인 Compressed Class Size의 가상 사이즈를 지정한다. 디폴트 값은 1GB이며 최대값은 3G이다.

 

GC와 연관된 이야기

위에서 이야기한 것처럼 Metaspace 공간의 릴리즈는 오직 클래스가 업로드되고 GC가 일어날 때만 발생한다. 따라서, Heap 영역 입장에선 GC를 통해 얻을 수 있는 것이 많지 않은 경우라도, Metaspace내의 오래된 클래스 메타데이터 청소를 위해 GC가 수행되는 것이 효율적일 수 있다.

 

Metaspace에서 유도되는 GC는 대표적을 두가지가 있다.

  • Metaspace 할당 시 : 지속적으로 Metadata를 쌓으면서 Metaspace를 확장시키는 대신, Metaspace의 효율적 활용을 위해 어느 임계 지점에서는 오래된 클래스로더들을 GC를 통해 정리하는 시도를 한다.
  • Metaspace OOME 시 : 커밋된 메모리의 합계가 MaxMetaspaceSize를 넘었거나, Compressed Class Space가 부족할 때 GC가 사용될 수 있다.

 

*Conference (순서대로 메타스페이스, 메타데이터, Native Memory)

https://jaemunbro.medium.com/java-metaspace%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90-ac363816d35e

 

[Java] 자바 메타스페이스(Metaspace)에 대해 알아보자.

Java Metaspace

jaemunbro.medium.com

https://veneas.tistory.com/entry/Java-Annotation-%EB%A9%94%ED%83%80%EB%8D%B0%EC%9D%B4%ED%84%B0

 

[Java] Annotation (메타데이터)

1. 어노테이션 (Annotation) @AnnotationName 어노테이션 = 메타데이터 메타데이터란 애플리케이션이 처리해야 할 데이터가 아니라, 컴파일 과정과 실행 과정에서 코드를 어떻게 컴파일하고 처

veneas.tistory.com

https://m.post.naver.com/viewer/postView.nhn?volumeNo=23726161&memberNo=36733075 

 

[Java Memory Profiling에 대하여] ① JVM 메모리 이해와 케이스 스터디

[BY 삼성SDS] About OOMEOOME란 Out Of Memory Error의 첫글자를 따서 약어처럼 쓰는 전세계에서 통용되...

m.post.naver.com

 

'Java' 카테고리의 다른 글

동일성(identity)과 동등성(equality)  (0) 2022.08.01
객체지향 5대 원칙 SOLID  (0) 2022.08.01
정적 (static)  (0) 2022.07.28
면접 준비 : 클래스와 객체  (0) 2022.07.28
어노테이션  (0) 2022.07.20