Skip to content

Commit 70750c3

Browse files
committed
feat: add jvm-tuning.mdx
1 parent 8e2458f commit 70750c3

File tree

3 files changed

+145
-0
lines changed

3 files changed

+145
-0
lines changed

posts/java/jvm-tuning.mdx

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
---
2+
title: "JVM Tuning"
3+
date: "2021-05-30"
4+
tags: ["Java"]
5+
summary: "Let's learn about JVM Memory, Life Cycle, and Non-Standard Options"
6+
description: "JVM Memory 영역, Life Cycle, Non-Standard Options 에 대해서 알아보자"
7+
---
8+
9+
:::info
10+
JVM Memory 영역, JVM Life Cycle, OOME(Out Of Memory Error) 가 발생하는 Case
11+
JVM 메모리 할당과 Java Stack/Heap Space 와 메모리 할당 정리
12+
JVM 표준 옵션인 Standard Options와 JVM 버전와 OS 종류에 따라 존재 여부가 결정되는 Non-Standard Options 중, Non-Standard Options 정리
13+
:::
14+
15+
16+
---
17+
18+
### JVM Memory 영역
19+
20+
<div style={{ textAlign: 'center' }}>
21+
<img src="/img/post/java/jvm/jvm-memory.png" alt="jvm-memory" style={{ display: 'inline-block' }} />
22+
</div>
23+
24+
1. Heap Memory
25+
* JVM 이 객체 또는 동적 데이터를 저장하는 곳 / Garbage Collection 이 일어 나는 곳
26+
2. Thread Stack
27+
* Stack Memory 영역이며, 프로세스의 쓰레드 당 하나의 스택 메모리가 있고, 메소드의 결과 / 반환 값을 저장하거나 지역변수를 저장하는 용도
28+
3. MetaSpace
29+
* 클래스 로더에서 클래스 정의를 저장하는데 사용
30+
* 이 공간이 계속 커지면 OS는 여기에 저장된 데이터를 가상 메모리로 이동하여애플리케이션 속도를 저하시킬 수 있음
31+
4. Code Cache
32+
* 컴파일러가 데이터를 저장하는 영역
33+
5. Sharded Library
34+
* 애플이케이션에서 사용할 공유 라이브러리가 기계어로 변환된 채 저장된 영역
35+
36+
37+
---
38+
39+
### JVM Life Cycle
40+
41+
<div style={{ textAlign: 'center' }}>
42+
<img src="/img/post/java/jvm/jvm-life-cycle.png" alt="vm-life-cycle" style={{ display: 'inline-block' }} />
43+
</div>
44+
45+
#### Minor Garbage Collection
46+
* New 영역에서 일어나는 Garbage Collection
47+
* Eden 영역에 객체가 가득 차게 되면 첫번째 Garbage Collection 발생
48+
* Survivor 1 영역에 값 복사
49+
* Survivor 2 영역을 제외한 나머지 영역의 객체들 삭제
50+
* Eden 영역과 Survivor 1 영역의 메모리가 기준치 이상일 경우, Eden 영역에 생성된 객체와 Survivor 1 영역에 있는 객체 중 참조되고 있는 객체가 있는 검사
51+
* 참조되고 있는 객체를 Survivor 2 영역에 복사
52+
* Survivor 2 영역을 제외한 영역의 객체들을 삭제
53+
* 일정 시간 이상 참조 되고 있는 객체들을 Old 영역으로 이동
54+
55+
#### Major Garbage Collection
56+
* Old 영역에 있는 모든 객체들을 검사
57+
* 참조되지 않은 객체들을 한번에 삭제
58+
* Minor Garbage Collection 에 비해 시간이 오래 걸리고 실행 중 프로세스가 정지
59+
60+
61+
---
62+
63+
### OOME(OutOfMemoryError) 발생하는 Cases
64+
65+
#### 1. 'java.lang.OutOfMemoryError': Java heap space
66+
* Java Heap 공간에 새로운 개체를 생성할 수 없을 때 발생
67+
* 지정한 Heap 크키가 Application 에 충분하지 않은 경우 발생
68+
→ Heap Size 조정
69+
70+
71+
#### 2. 'java.lang.OutOfMemoryError': Metaspace
72+
* Java class metadata 는 원시 메모리에 할당되는데, class metadata 가 할당될 메타공간이 모두 소모 되면 발생
73+
→ MaxMetaSpaceSize 값을 늘려 설정, Heap Size를 줄이면 더 많은 공간을 확보 할 수 있음(Heap과 동일한 주소 공간에 할당 됨)
74+
75+
#### 3. 'java.lang.OutOfMemoryError': requested size bytes for reason. Out of swap space?
76+
* JVM은 Heap 외에도 자체 구동을 위해 native heap 사용하는데, native heap 이 부족할 때 발생(Heap Size 가 너무 클 경우)
77+
* heap 영역과 perm 영역을 과하게 설정한 경우, native, stack 영역이 적은 공간으로 설정되어 두 영역의 공간 부족이 나는 경우
78+
→ 메모리가 부족해서 swap 을 쓰는 경우 성능이 급격히 저하되므로, 원인을 찾아 제거
79+
80+
#### 4. 'java.lang.OutOfMemoryError': GC Overhead limit exceeded
81+
* Garbage Collector 실행과정에서 Java 프로그램이 느려지는 경우 발생
82+
* Garbage 수집 후 Java Process 가 Java Collection 을 수행하는데 걸리는 시간의 약 98% 이상 소비하고 Heap 의 2% 미만이 복구 된 상태에서
83+
지금까지 수행하는 과정에서 Garbage Collection 중 java.lang.OutOfMemoryError 가 5번 이상 생성되는 경우 발생
84+
* 데이터를 할당하는데 필요한 공간이 Heap 에 없는 경우 발생
85+
→ Heap Size를 늘린다.
86+
87+
:::warning
88+
참고) -XX:-UseGCOverheadLimit 로 초과 오버헤드 GC 제한 명령을 해제할 수 있음
89+
:::
90+
91+
92+
---
93+
94+
### Non-Standard Options (일부)
95+
96+
| Section | Option | Description |
97+
|--|--|--|
98+
| Extra Options | Xss | 쓰레드 스택 크기(바이트)를 설정. 기본 값은 플랫폼에 따라 다름, (각 Thread에 할당되는 Stack Size 설정) <br/> Default: Linux/x64(64bit): 1024KB / macOS(64bit): 1024KB / Oracle Solaris/x64(64bit): 1024KB, / Windows: 기본 값은 가상 메모리에 따라 다름|
99+
| | Xms(-XX:InitialHeap Size) | 초기 Heap Size 설정 <br/> Default: JVM을 server class로 실행시 초기 heap size는 메모리의 1/64 |
100+
| | Xmx(-XX:MaxHeapSize) | 최대 Heap Size 설정 <br/> Default: JVM을 server class로 실행시 최대 heap size는 메모리의 1/4 |
101+
| Advanced Runtime Options | XX:MaxDirectMemorySize | java.nio 패키지의 최대 총 크기(바이트)를 직접 버퍼 할당으로 설정. <br/> JVM이 NIO Direct-buffer 할당의 크기를 자동적으로 선택함을 의미 <br/> (default:0)|
102+
| | XX:ActiveProcessorCount | Garbage Collection 과 ForkJoinPool 과 같은 다양한 작업에 사용할 쓰레드 풀의 크기를 계산하는데 VM이 사용할 CPU 수를 재정의 <br/> 이 플래그는 도커 컨테이너에서 여러 Java 프로세스를 실행할 때 CPU 리소스를 분할 하는데 유용|
103+
| Advanced Garbage Collection Options | XX:MaxMetaspaceSize | 클래스 메타데이터에 할당할 수 있는 최대 기본 메모리 양을 설정. <br/> 기본적으로 크기 제한 X, 응용 프로그램의 메타데이터 크기는 응용 프로그램 자체, 실행 중인 다른 응용 프로그램 및 시스템에서 사용할 수 있는 메모리 양에 따라서 달라짐.|
104+
| Advanced JIT Compiler Options | XX:ReservedCodeCacheSize | JIT 컴파일 코드에 대한 최대 코드 캐시 크기를 설정 <br/> (default:240MB) |
105+
106+
---
107+
108+
### ALL
109+
:::note
110+
전체의 Options 은 [공식페이지](https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE)에서 확인
111+
:::
112+
113+
큰 틀에서의 Options 구분은 아래와 같다.
114+
115+
| Section | Description |
116+
|--|--|
117+
| Extra Options | Java HotSpot Virtual Machine에만 해당 되는 범용 옵션 |
118+
| Advanced Runtime Options | Java HotSpot VM의 런타임 동작을 제어 |
119+
| Advanced JIT Compiler Options | Java HotSpot VM에서 수행하는 동적 JIT(Just-In-Time) 컴파일을 제어 |
120+
| Advanced Serviceability Options | Java용 고급 서비스 가능성 옵션 |
121+
| Advanced Garbage Collection Options | Garbage collection이 Java HotSpot VM에 의해 수행되는 방법 제어 |
122+
123+
----
124+
125+
### 💡 **Tips**
126+
127+
#### Xmx, XmX 동일하게 세팅
128+
* init과 max 사이에서 Used 메모리가 committed까지 사용하게 되면, 신규 메모리 공간을 요구하는데 약 1초 가량 JVM 메모리 할당 중 멈춰버리는 경우가 발생할 수 있음
129+
(init < used < committed < max)
130+
131+
:::neutral
132+
Setting -Xms and -Xmx to the same value increases predictability by removing the most important sizing decision from the virtual machine. However, the virtual machine is then unable to compensate if you make a poor choice.
133+
:::
134+
135+
#### 개별 Thread 의 Stack Size(-Xss)
136+
* Thread 별 Stack Size 를 과도하게 줄였을 경우 Stack Overflow Error 발생할 수 있음
137+
* 많은 수의 Thread 를 사용하는 Application 의 경우 Thread Stack 에 의한 메모리 요구량이 높아지며 이로 인해서 Out Of Memory Error 발생할 수 있음
138+
139+
---
140+
141+
:::success
142+
<b>Think..</b>
143+
✔ 대부분의 블로그나 참고 자료들은 JDK 8 이하의 버전에 대해서 설명한 것들이 많으므로 걸러서 봐야한다.
144+
✔ 대표적으로 JDK7 에서는 Heap Memory 영역에 Permanent Generation 영역이 있었지만, JDK8 부터 Native Memory 영역에 MetaSpace 가 생김.
145+
:::
25.9 KB
Loading
39.5 KB
Loading

0 commit comments

Comments
 (0)