Skip to the content.

JVM을 공부하면서 Metaspace 영역에 대해 처음 알게 되었다. 이는 자바 리플렉션 API를 호출할 때 해당 객체가 어디에 생성되고 생명주기가 어떻게 관리되는지 알고 싶어서 찾아보게 되었다.

Metaspace 영역에는 클래스 로더가 클래스 파일들을 메모리에 올리면서 해당 클래스의 메타 정보들을 저장한다. 이 영역은 Java 8 이전 버전에 있었던 Permanent Generation(이하 PermGen) 영역을 대체하였다.

Metaspace가 PermGen을 대체하게 된 주요 이유는 다음과 같다:

  1. PermGen은 최대 메모리가 고정되어 있어 OutOfMemoryError가 발생하기 쉬웠다.
  2. Metaspace는 OS 수준의 네이티브 메모리를 사용하여 필요에 따라 자동으로 크기가 조절된다.
  3. 클래스 메타데이터의 GC 효율성이 개선되었다.

클로드 참조

클로드 참조

Metaspace의 생명주기와 GC에 대해 알아보니, 흥미로운 점을 발견했다:

  1. Metaspace는 네이티브 메모리를 사용하지만, 완전히 GC의 범위 밖에 있는 것은 아니다.
  2. GC는 Metaspace를 간접적으로 관리한다.
  3. 클래스 로더가 더 이상 해당 클래스를 참조하지 않으면, 다음과 같은 과정이 일어난다:
       - 힙 영역에 있는 클래스 로더 객체와 관련 Class 객체들이 GC 대상이 된다.
       - 이와 연관된 Metaspace의 클래스 메타 정보들도 GC 대상이 된다.
       - Full GC나 특정 조건에서 Metaspace GC가 발생하면, 이 메타 정보들이 정리된다.

주의할 점은 모든 GC 사이클에서 이 과정이 일어나는 것은 아니며, 시스템 클래스 로더나 부트스트랩 클래스 로더가 로드한 클래스들은 일반적으로 JVM 생명주기 동안 유지된다는 것이다.

이러한 Metaspace의 특성 덕분에 Java 애플리케이션은 더 효율적으로 메모리를 관리할 수 있게 되었고, PermGen 시대에 비해 OutOfMemoryError 발생 빈도가 크게 줄어들었다.