117 lines
5.9 KiB
Markdown
117 lines
5.9 KiB
Markdown
### Gc tuning 절차 간단히 맛보기
|
||
|
||
[[GC]] 상황을 모니터링하며 현재 운영되는 시스템의 GC 상황을 확인한다.
|
||
```bash
|
||
# jstat gcutil 명령어로 현재 실행중인 8884번 프로세스에 대해 1초에 한번 씩 총 10번 GC와 관련된 정보를 출력하도록 모니터링
|
||
jstat -gcutil -t 8844 1000 0
|
||
```
|
||
|
||
![[jstat.png]]
|
||
|
||
| 컬럼 | 설명 |
|
||
| ---- | -------------------------------- |
|
||
| S0 | Survivor 영역 0의 사용율(현재 용량에 대한 비율) |
|
||
| S1 | Survivor 영역 1의 사용율(현재 용량에 대한 비율) |
|
||
| E | Eden 영역의 사용율 (현재 용량에 대한 비율) |
|
||
| O | Old 영역의 사용율 (현재 용량에 대한 비율) |
|
||
| P | Permanent 영역의 사용율 (현재 용량에 대한 비율) |
|
||
| YGC | Young 세대의 GC 이벤트 수 |
|
||
| YGCT | Young 세대의 GC 시간 |
|
||
| FGC | Full GC 이벤트 수 |
|
||
| FGCT | Full GC 시간 |
|
||
| GCT | GC 총 시간 |
|
||
|
||
#### **2.** **모니터링 결과 분석 후 GC 튜닝 여부 결정**
|
||
|
||
GC 상황을 확인한 후에는, 결과를 분석하고 GC 튜닝 여부를 결정해야 한다.
|
||
|
||
- **Minor GC 수행시간** : YGCT / YGC (0.314 / 19) = 0.016초
|
||
- **Major GC 수행 시간** : FGCT / FGC (0.291 / 3) = 0.097초
|
||
|
||
![[jstat 2.png]]
|
||
|
||
만약 모니터링 결과가 다음의 조건에 모두 부합한다면, GC 튜닝이 굳이 필요하지는 않다.
|
||
|
||
- Minor GC의 처리 시간이 빠르다 (50ms 내외)
|
||
- Minor GC의 주기가 빈번하지 않다 (10초 내외)
|
||
- Full GC의 처리 시간이 빠르다 (1초 내외)
|
||
- Full GC의 주기가 빈번하지 않다 (10분에 1회)
|
||
|
||
#### **3.** **GC 알고리즘 방식 지정**
|
||
|
||
위의 모니터링 결과를 보고, GC 튜닝을 진행하기로 결정했다면 GC 알고리즘 방식을 선정한다.
|
||
|
||
이때 서버가 여러 대이면 서버에 GC 옵션들을 서로 다르게 각각 지정해서, 현재 내 어플리케이션의 GC 알고리즘에 따른 차이를 확인하는 것이 좋다. (알고리즘이 더 최신이라고 해서 반드시 내 어플리케이션에서 해당 GC 방식이 적절하다라고 보증 할수 없다)
|
||
|
||
| | |
|
||
|---|---|
|
||
[[GC Algorithm]]
|
||
[[Parallel GC]]
|
||
- **'처리량'이 중요한 시스템에서 주로 사용** <br>- Full GC 수행 시 compaction 작업이 수행되기 때문에 GC 시간 자체는 많이 소요되나 일정한 멈춤 시간을 제공함|
|
||
CMS GC|
|
||
- **응답시간이 중용한 시스템에사 주로 사용** <br>- compaction 미수행으로 Stop-The-World 시간은 짧으나 자주 Compaction이 발생하는 시스템의 경우 오히려 Full GC 보다 Compation 시간이 오래 걸릴 수 있음 <br>- 자원 사용량이 증가하는 점도 고려해야 함|
|
||
G1 GC|
|
||
- 성능적으로 가장 우수한 GC 방식이나, JDK 7 버전부터 정식 제공되었으며, Java 9 에서 Default GC 방식으로 채택|
|
||
#### **4. 힙 메모리 크기 지정**
|
||
|
||
[[JVM Heap Area]]는 크기에 따라 GC 발생 횟수와 수행 시간에 영향을 끼치기 때문에 옵션을 통해 조절하면 어플리케이션 성능 향상 효과를 가져올 수 있다.
|
||
|
||
여기서 말하는 메모리 크기는 JVM의 시작 크기(-Xms)와 최대 크기(-Xmx)를 말한다.
|
||
[[Xms, Xmx]]
|
||
|
||
메모리 크기와 GC 발생 횟수, GC 수행 시간의 관계는 다음과 같다.
|
||
|
||
- 메모리 크기가 크면,
|
||
- GC 발생 횟수는 감소한다.
|
||
- GC 수행 시간은 길어진다.
|
||
- 메모리 크기가 작으면,
|
||
- GC 발생 횟수는 짧아진다.
|
||
- GC 수행 시간은 증가한다.
|
||
|
||
| 구분 | 옵션 | 설명 |
|
||
| ------------- | ------------------ | ------------------------ |
|
||
| 힙(heap) 영역 크기 | \-Xms | JVM 시작 시 힙 영역 크기 |
|
||
| 힙(heap) 영역 크기 | \-Xmx | 최대 힙 영역 크기 |
|
||
| New 영역의 크기 | \-XX:NewRatio | New 영역과 Old 영역의 비율 |
|
||
| New 영역의 크기 | \-XX:NewSize | New 영역의 크기 |
|
||
| New 영역의 크기 | \-XX:SurvivorRatio | Eden 영역과 Survivor 영역의 비율 |
|
||
|
||
|
||
> [!note] 이 중에서 중요한 옵션은 -Xms 옵션, -Xmx 옵션, -XX:NewRatio 옵션이다.
|
||
특히 ==-Xms 옵션과 -Xmx 옵션은 왠만하면 필수로 지정하길 권장==하며, 그리고 NewRatio 옵션을 어떻게 설정하느냐에 따라서 GC 성능에 많은 차이가 발생한다.
|
||
==NewRatio는 New 영역과 Old 영역의 비율이다.==
|
||
-XX:+NewRatio=1로 지정하면 (New 영역):(Old 영역)의 비율은 1:1이 된다.
|
||
만약 1GB라면 (New 영역):(Old 영역)은 500MB:500MB가 된다.
|
||
NewRatio가 2이면 (New 영역):(Old 영역)이 1:2가 된다.
|
||
즉, **값이 커지면 커질수록 Old 영역의 크기가 커지고 New 영역의 크기가 작아진다.**
|
||
|
||
```bash
|
||
# 힙 시작 크기 256mb, 힙 최대 크기 2gb
|
||
# young 영역과 old 영역 비율 1:2 로 설정 (New 영역:Old 영역 = 1:2)
|
||
# Parallel GC 로 실행
|
||
java -Xms256m -Xmx2048m -XX:+NewRatio=2 -XX:+UseParallelGC
|
||
```
|
||
|
||
#### **5.** **튜닝 결과 분석**
|
||
|
||
GC 옵션을 지정하고 24시간 이상(하루, 이틀) 데이터를 수집한다.
|
||
|
||
그리고 로그를 분석해 메모리가 어떻게 할당되는지 확인한다.
|
||
|
||
그 다음에 GC 방식 / 메모리 크기를 변경해 가면서 최적의 옵션을 찾아 나가면 된다.
|
||
|
||
분석할 때는 다음의 사항을 중심으로 살펴보는 것이 좋다. 이는 우선 순위 별로 나열되어 있다.
|
||
|
||
1. FullGC 수행 시간
|
||
2. MinorGC 수행 시간
|
||
3. Full GC 수행 간격
|
||
4. MinorGC 수행 간격
|
||
5. 전체 Full GC 수행 시간
|
||
6. 전체 Minor GC 수행 시간
|
||
7. 전체 GC 수행 시간
|
||
8. Full GC 수행 횟수
|
||
9. Minor GC 수행 횟수
|
||
|
||
#### **6.** **전체 서버에 반영 및 종료**
|
||
|
||
GC 튜닝 결과가 만족스러우면 전체 서버에 GC 옵션을 적용하고 마무리한다. |