본문으로 건너뛰기
개발 머꼬
개발 노트Java
hohyeon.dev19

Java GC pause 증가, heap 크기보다 먼저 볼 세 가지

  • #Engineering Note
  • #GC
  • #Java
  • #Memory

문제 발생

평소 100ms 안에 끝나던 요청이 간헐적으로 2초 이상 걸리고 같은 시각에 GC log가 보입니다. 시간대가 겹친다는 사실만으로 GC가 원인이라고 확정할 수는 없습니다. CPU 포화나 safepoint, 외부 I/O 대기도 같은 지연을 만들 수 있습니다.

pause 증가는 heap 크기 하나보다 live-set, allocation rate, collector와 concurrent phase 실패를 GC log·JFR로 확인해야 합니다.

원인 분석

세 값을 같은 시간축에 놓습니다. 첫째, 실제 pause 시간과 원인입니다. 둘째, 단위 시간당 새 객체가 만들어지는 allocation rate입니다. 셋째, GC 뒤에도 남는 live set입니다. allocation rate만 높고 live set이 안정적이면 임시 객체가 많을 가능성이 있고, live set이 계속 증가하면 오래 보유되는 참조를 더 살펴야 합니다. heap 사용률 한 장이나 평균 latency만으로 둘을 구분할 수 없습니다.

java -Xlog:gc*:file=gc.log:time,uptime,level,tags \
  -XX:StartFlightRecording=filename=app.jfr,dumponexit=true \
  -jar app.jar

해결 방안

JFR과 GC log에서 pause가 실제 느린 요청과 일치하는지 먼저 확인합니다. allocation이 원인이면 반복문 안 임시 collection, 큰 문자열·배열 복사처럼 가장 큰 할당 지점을 줄입니다. live set 증가라면 class histogram과 heap dump의 GC root 보유 경로를 확인합니다. collector나 -Xmx 변경은 같은 workload에서 p95·p99, 처리량, pause, live set과 전체 RSS가 함께 나아질 때만 채택합니다.

공식 문서

JDK version, collector, container memory limit과 실제 workload에서 다시 측정합니다.

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.