Java application의 속도가 느려질 때 Garbage collection이 원인인지 확인하는 방법을 정리한다.

개요

Garbage Collection 이란?

Java 응용프로그램은 명시적으로 메모리를 할당하는 대신 Java Virtual Machine (이하 JVM)에서 자동으로 필요한 메모리를 할당하고 사용이 끝나면 자동으로 해제한다. Java Heap Memory는 JVM에게 할당된 메모리이다.

JVM은 여유 메모리가 부족할 경우 사용된 메모리를 해제하는 작업을 수행하는데, 이를 Garbage Collection 이라 한다.

Garbage Collection 현황 보기

$ <JDK home>/bin/jstat -gccause <java pid> <출력 주기: in milliseconds>

정상 상태 출력 예)

# /opt/jdk1.8.0_144/bin/jstat -gccause 3057 1000
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC                 
  0.00 100.00  66.67  82.79  93.48  88.16   1447   74.806     0    0.000   74.806 G1 Evacuation Pause  No GC               
  0.00 100.00  66.67  82.79  93.48  88.16   1447   74.806     0    0.000   74.806 G1 Evacuation Pause  No GC               
  0.00 100.00  66.67  82.79  93.48  88.16   1447   74.806     0    0.000   74.806 G1 Evacuation Pause  No GC               
  0.00 100.00  66.77  82.79  93.48  88.16   1447   74.806     0    0.000   74.806 G1 Evacuation Pause  No GC               
  0.00 100.00  66.77  82.79  93.48  88.16   1447   74.806     0    0.000   74.806 G1 Evacuation Pause  No GC

Heap memory 부족 상태 출력 예)

# /opt/jdk1.8.0_144/bin/jstat -gccause 30602 2000
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
0.00 0.00 49.22 100.00 80.93 74.55 43576 4234.528 7460 19203.562 23438.091 Allocation Failure No GC
0.00 0.00 67.15 100.00 80.93 74.55 43576 4234.528 7460 19203.562 23438.091 Allocation Failure No GC
0.00 0.00 80.24 100.00 80.93 74.55 43576 4234.528 7460 19203.562 23438.091 Allocation Failure No GC
0.00 0.00 87.93 100.00 80.93 74.55 43576 4234.528 7460 19203.562 23438.091 Allocation Failure No GC
0.00 0.00 94.89 100.00 80.93 74.55 43576 4234.528 7460 19203.562 23438.091 Allocation Failure No GC
0.00 0.00 100.00 100.00 80.93 74.55 43576 4234.528 7461 19203.562 23438.091 Allocation Failure Ergonomics
0.00 0.00 24.03 100.00 80.93 74.55 43576 4234.528 7461 19205.756 23440.284 Allocation Failure No GC


GC 관련 JVM 옵션

옵션설명
-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode
증분으로 Garbage Collection 수행하여 한 번에 많은 GC 수행으로 인한 동작 지연 방지
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps
Tomcat의 catalina.out에 GC 관련 정보 출력
-XX:+UseCompressedOops
64비트 JVM에서 일반 개체 포인터에 필요한 메모리를 줄여서 공간 절약
-XX:NewSize=200m -XX:MaxNewSize=200m"
Young Generation을 제한하여 보다 자주 GC를 수행하는 효과 기대


설정 예)

MEM_OPTIONS="-Xms4096M -Xmx4096M -XX:PermSize=512m -XX:MaxPermSize=512m 
             -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode
             -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
             -XX:+UseCompressedOops
             -XX:NewSize=200m -XX:MaxNewSize=200m"

참고

Young Generation and Old Generation

Heap Structure:

Heap Structure