7 -> 8 메모리 구조 변화
JDK 8 버전부터는 JDK 7 버전까지 사용되었던 `PermGen(Permanent Generation의 약자)`가 제거되고, `Metaspace`라는 영역이 Native Memery에 추가되었다.
1. PermGen(Permanent Generation)
PermGen이란 JDK 7 버전까지 사용되던 메모리 구조로 클래스 메타데이터, 상수 풀, static 변수 등을 저장하는 데 사용되었다.
아래 이미지와 같이 JVM 메모리상 위치는 heap 영역 내부에 포함되어 있다. 기본적으로 힙 영역에 있으니 고정된 크기를 할당받는다.
❌ PermGen 방식의 문제점
PermGen 영역의 크기는 힙 영역 안에 존재하므로, 고정된 크기의 메모리 영역이다. 그렇기 때문에 실행이 되는 도중에는 사이즈에 변경이 불가능하다.
- `-XX:MaxPermSize` 옵션을 통해 크기를 설정할 수 있지만, 고정된 크기이므로 초과하면 `OOM(Out Of Memery)`가 발생하게 된다.
- 특히, 클래스를 많이 로드하는 애플리케이션(Spring, Hibernate 등)을 실행할 때 문제가 심각하다.
- 클래스 로드가 많아질수록 PermGen 공간이 부족해지는 문제가 발생하게 된다.
기본적으로 JVM Heap 영역에 위치한다는 것은 GC에 의해 메모리가 관리됨을 의미한다. 클래스 로더(ClassLoader)는 클래스를 동적으로 로드하고, 필요 없으면 GC가 제거하는 방식으로 동작하게 된다. 하지만 PermGen에 저장된 클래스 메타데이터는 GC가 쉽게 회수하지 못하는 경우가 많다.
- 클래스를 자주 로드/언로드하는 경우, PermGen이 조각화(Fragmentation)되어 메모리 누수가 발생한다.
- 특히 Spring, Hibernate 같은 프레임워크는 동적으로 클래스를 로드하기 때문에 PermGen OOM이 발생할 가능성이 높다.
- PermGen에 저장된 상수 풀(Constant Pool)이 GC에 의해 해제되지 않는 경우가 많아 불필요한 메모리 점유가 지속된다.
결론적으로 말하면 PermGen을 사용하면 메모리 부족 문제(OOM)에 발생할 가능성이 높아지게 된다.
2. Metaspace
JDK 8 버전 이후부턴 JVM의 메모리 영역의 Permanent Generation 메모리 영역이 사라지고 Metaspace 영역이 생기게 되었다.
Metaspace에서는 클래스 로더가 런타임 중에 읽어온 정보가 저장된다.
- Class 구조
- Method 정보, Exception 정보, 바이트 코드
- Constant Pool
- Annotation
PermGen과 가장 큰 차이점은 메모리의 위치이다. PermGen에 경우 힙 영역 내부에 있다고 했는데, Metaspace에 경우 `Native Memory`의 위치하게 된다.
Heap 영역은 JVM에 의해 관리되는 영역이며, Native Memory는 OS에 의해 관리되는 영역이다.
⭕ Metaspace의 도입으로 개선된 점
Metaspace는 PermGen의 이런 문제를 해결하기 위해, JVM의 Heap이 아닌 OS의 네이티브 메모리를 사용하여 유연한 메모리 할당이 가능하도록 설계되었다.
PermGen의 JVM Heap 내부에 존재함으로 초기 고정된 값으로 진행되지만, Native Memory 영역에 있는 Metaspace는 OS가 자동으로 크기를 조절하기 때문에 개발자가 영역 확보의 상한을 크게 의식할 필요가 없어졌다.
PermGen에서는 GC가 클래스 메타데이터를 직접 관리해야 했지만, Metaspace에서는 필요한 경우 자동으로 메모리를 반환하므로 GC 부담이 줄어듬에 따라 GC 효율이 증가한다.
이러한 이점을 통해 메모리 부족 문제(OOM)가 개선되게 된다.
'Language > Java' 카테고리의 다른 글
[Java] 콜바이 밸류(Call by Value)와 콜바이 레퍼런스(Call by Reference) (0) | 2025.02.17 |
---|---|
[Java] 스레드와 자바 메모리의 관계 (0) | 2025.02.05 |
[Java] 제네릭(Generic) (1) | 2025.01.31 |
[Java] 자바 예외 처리 - 예외 계층, 체크 예외, 언체크 예외, 예외의 규칙 (0) | 2025.01.31 |
[Java] Class 클래스 (0) | 2025.01.30 |