JDK 8부터 자바는 기존의 PermGen(Permanent Generation) 영역을 제거하고, Native Memory를 사용하는 Metaspace를 도입했다.
PermGen이란?
PermGen
(이하 Perm) 영역은 JDK 7까지 존재했던 메모리 영역으로, 클래스 메타데이터와 런타임 중에 읽힌 클래스 및 메서드 정보 등을 저장하는 공간이었다.
Perm에 저장되는 데이터
- 클래스 메타데이터(클래스 이름, 메서드 이름, 필드 이름 등)
- 런타임 상수(Constant Pool)
- Static 변수(JDK 8 이전)
- 메서드와 바이트코드
Perm
영역은 힙(Heap) 외부에 위치하며, JVM 실행 시 크기가 고정된다.
하지만 이 고정된 크기는 메모리 부족 문제를 자주 일으켰다. 동적으로 클래스들이 로드되고 Static 변수나 상수가 Perm 영역에 계속 쌓이면서 OutOfMemoryError
이 자주 발생했다.
JDK 8에서는 이 문제를 해결하기 위해 Perm
을 제거하고, Perm
영역에서 관리하던 것들을 Metaspace
로 옮기게 되었다. 즉, 각종 메타 정보를 OS가 관리하는 영역으로 옮겨 Perm
영역의 사이즈 제한을 없앤 것이라 할 수 있다.
이 과정에서 Static 변수는 Heap 영역으로 옮겨져서 GC의 대상이 되었다.
PermGen 제거 -> Metaspace 도입
Metaspace는 JVM의 새로운 클래스 메타데이터 저장소로, 클래스 로더가 런타임 중에 읽어온 정보가 저장된다.
Metaspace에 저장되는 데이터
- 클래스 구조 정보(필드, 메서드, 바이트코드 등)
- 예외 정보
- Constant Pool
- Annotation
Perm영역이 Metaspace로 옮겨짐으로써 가장 중요한 차이는 Metaspace가 Heap 메모리가 아닌 Native Memory를 사용한다는 점이다.
Native Memory를 활용하는 Metaspace는 JVM 힙 메모리와 독립적이므로, 운영체제가 직접 관리한다.
즉, Metaspace의 크기는 런타임 중 동적으로 확장되기 때문에 개발자가 이를 별도로 관리할 필요가 없는 것이다.
Metaspace 도입 이후의 변화
JDK 8부터 PermGen이 제거되고 Metaspace가 도입됨으로써 변화는 다음과 같다.
1. Static 변수와 상수 풀 관리의 변화
기존 PermGen에서 관리되던 Static 변수와 상수(Constant Pool)는 이제 Java Heap 영역으로 옮겨져 GC의 대상이 되었다. 이를 통해 메모리 관리가 더 효율적으로 이루어졌으며, 메모리 누수 가능성도 줄어들었다.
2. 클래스 메타데이터 관리의 유연성
Metaspace는 PermGen과 마찬가지로 클래스 메타데이터를 저장한다. 하지만 Native Memory를 활용하기 때문에 메모리 크기를 OS가 자동으로 조정할 수 있다.
즉, 개발자가 PermGen 크기(-XX:PermSize
, -XX:MaxPermSize
)를 지정할 필요가 없어졌다.
3. OutOfMemoryError 문제 완화
PermGen의 고정 크기 제약이 없어지면서 메모리 부족으로 인한 OutOfMemoryError
문제가 발생할 가능성이 줄어들었다.
'💻 Dev > Java' 카테고리의 다른 글
Out-of-Memory(OOM)는 왜 발생하고, 어떻게 예방할까? (0) | 2024.11.30 |
---|---|
instanceof 사용을 지양해야하는 3가지 이유 (0) | 2024.11.29 |
JVM Warm-up, feat. 스프링 첫 요청이 오래 걸리는 이유 (0) | 2024.11.28 |
가비지 컬렉터(GC) feat.힙 영역 (0) | 2024.11.23 |
자바는 Call by Value만 사용한다. (0) | 2024.11.22 |
String Constant Pool, feat. Runtime Constant Pool (0) | 2024.11.02 |