0612
# 0612
# JVM 메모리 구조(자바 7,8 기준)
JVM 메모리 구조를 자바 7, 8버전 을 기준으로 알아보자.
# JVM 메모리 구조
- Java 7 Hotspot JVM 구조
<----- Java Heap -----> <--- Native Memory --->
+------+----+----+-----+-----------+--------+--------------+
| Eden | S0 | S1 | Old | Permanent | C Heap | Thread Stack |
+------+----+----+-----+-----------+--------+--------------+
<--------->
Permanent Heap
S0: Survivor 0
S1: Survivor 1
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- Java 8 Hotspot JVM 구조
<----- Java Heap -----> <--------- Native Memory --------->
+------+----+----+-----+-----------+--------+--------------+
| Eden | S0 | S1 | Old | Metaspace | C Heap | Thread Stack |
+------+----+----+-----+-----------+--------+--------------+
* Java Heap: JVM이 관리하는 영역
* Native Memory: OS에서 관리하는 영역
1
2
3
4
5
6
2
3
4
5
6
Java 7은 Permanent Generation
영역이 존재하고, Java 8 이후 해당 영역은 삭제되고 Metaspace
영역이 추가됐다.
Java7까지의 Permanent Generation 영역은 JVM 관리하는 메모리 영역이였지만 Java8 이후 추가된 Metaspace 영역은 OS에서 관리하는 Native 메모리 영역으로 변경되었다.
# Permanent Generation 와 Metaspace
Permanent Generation과 Metaspace는 간단히 말해 Java의 Classloader가 로드한 Class의 Metadata를 저장하기 위해 Hotspot JVM에서 구현한 Method 영역이다.
# Permanent Generation
- Permanent Generation는 다음과 같은과 같은 정보를 저장한다.
- Class의 Meta정보 (pkg path 정보라고 보면 됨, text 정보)
- Method의 Meta 정보
- Static Object
- 상수화된 String Object
- Permanent Generation은 JVM에 의해 크기가 강제되던 영역이다.
- 메모리 옵션
- -XX:PermSize=N --> PermGen Default Size 설정
- -XX:MaxPermSize=N --> PermGen Max Size 설정
# Metaspace
- Metaspace는 Permanent Generation과 동일하게 class들의 metadata가 저장되는 공간이다.
- Metaspace는 Permanent Generation과 달리 Native Memory 영역에 위치한다.
- Metaspace는 Native Memory 영역에 위치하므로 OS가 자동으로 크기를 조절한다.
- 옵션으로 Metaspace의 크기를 줄일 수도 있다.
- -XX:MetaspaceSize=N --> Metaspace Default Size 설정
- -XX:MaxMetaspaceSize=N --> Metaspace Max Size 설정
- 옵션으로 Metaspace의 크기를 줄일 수도 있다.
- Java 8부터는 Permanent Generation 관련 JVM 옵션은 무시한다.
# 변경된 사항
- class meta-data는 native memory로 이동된 Metaspace에 저장하고 permanent에 저장했던 static 변수와 interned strings는 heap 영역으로 보내져서 GC의 대상이 되도록 했다.
Java 7 | Java 8 | |
---|---|---|
Class 메타 데이터 | 저장 | 저장 |
Method 메타 데이터 | 저장 | 저장 |
Static Object 변수, 상수 | 저장 | Heap 영역으로 이동 |
메모리 튜닝 | Heap, Perm 영역 튜닝 | Heap 튜닝, Native 영역은 OS가 동적 조정 |
메모리 옵션 | -XX:PermSize -XX:MaxPermSize | -XX:MetaspaceSize -XX:MaxMetaspaceSize |
- PermGen에 속한 Method area가 클래스 변수를 저장한다고 알고 있다면 이해하기 쉽지 않다. static 변수는 클래스 변수로 명시적 null 선언이 되지 않으면 gc되어서는 안되는 변수다. Method area가 클래스 변수를 저장한다고 이해하는 시점에서 오해가 발생한다 Method area는 class의 meat-data를 저장할 뿐 실질적인 객체와 데이터는 Method area 바깥의 PermGen에 저장됨을 알아야 한다.
# 결론
- Permanent Genration은 JVM이 관리하는 영역이라 사이즈 제한이 있었다. 허나 자바 8부터는 Metaspace가 Native 메모리를 이용함으로서 기존과 비교해 큰 메모리 영역을 사용할 수 있게 되었다.
- Perm 영역 크기로 인한 java.lang.OutOfMemoryError를 해결하게 됐습니다.