GC 로깅

GC 로그는 시스템 다운의 원인을 분석할 때 유용하다.

모든 중요한 애플리케이션에서는 두가지를 설정해야한다.

  • GC 로그를 생성한다.
  • 애플리케이션 출력과 별도로 특정 파일에 GC 로그를 보관한다.

GC 로깅 켜기

-Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintTenuringDistributuion -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps

필수 flag

flag operation
-Xloggc:gc.log GC event 로깅할 파일을 지정
-XX:+PrintGCDetails GC event 세부 정보를 로깅
-XX:+PrintTenuringDistributuion 툴링에 필요한 부가적인 GC event 세부 정보를 추가
사람이 확인하기 어려운 데이터지만 memory pressure, premature promotion 등 확인에 필요한 기본 데이터를 제공
-XX:+PrintGCTimeStamps GC event 발생 시간을 (VM 시작 이후 경과 시간으로) 초단위 출력
GC event와 application event를 연관짓는 용도로 사용
-XX:+PrintGCDateStamps GC event 발생 시간을 (시간 기준으로) 출력
GC event와 JVM event를 연관짓는 용도로 사용

Rotation flag

flag operation
-XX:+UseGCLogFileRotation log file rotation 기능을 켜기
-XX:+NumberOfGCLogFiles= rotation file 개수 설정
-XX:+GCLogFileSize= rotation file 최대 사이즈 설정

GC 로그 장점

JVM과 GC는 수 많은 component가 조합된 아주 복잡한 구현체.
성능 역시 예측하기가 굉장히 어렵다.
그렇기 때문에 GC를 모든 워크로드들이 특정 값으로 최적화할 수 없다.
이를 모니터링하고 GC 튜닝에 유용하게 사용되는 것이 GC 로그.

GC 로깅은 사실상 오버헤드가 거의 없기 때문에 주요 JVM 프로세스는 항상 로깅을 켜놓아야 한다.

  • JVM 내부에서 non-blocking write. 운영계에선 계속 켜놓는게 맞다.

GC 로그 파싱

GC 로그 메세지는 정해진 포맷이 따로 없다.
로그에 어떤 메세지를 남길지는 hotspot 개발팀 마음이라 minor release에서도 포맷이 다르기도 하다.
단순 로그 파싱은 어렵지 않지만 로그가 많이 복잡하다.
GC 설정을 변경하면 로그 포맷이 변경되고 파서가 동작하지 않는 경우도 있다.

따라서 로그를 스스로 파싱하려고하지 말고 반드시 로그 툴을 사용하자.

  1. 센섬
    • 상용 메모리 분석기 (유료)
    • 파싱, 정보 추출부터 시간 뷰, 전체 클러스터 뷰까지 제공
    • 센섬 개발팀이 openJDK code의 logging 소스를 분석해서 반영하기 때문에 철저하고 강력함
  2. GCViewer
    • 오픈소스 (무료)
    • 센섬보다 빈약한 기능
    • 로그 파싱, 그래프 출력등의 기본 기능만 있고 분석기능은 없음

GC 기본 튜닝

튜닝을 해야하는 이유

  1. GC가 성능 문제를 일으키는 원인인지 혹은 영향이 없는지 파악하는 비용은 크지 않다.
    • GC가 성능 문제를 일으키는지 밝히는건 쉽다.
    • 맞다면 더 구체적인 원인 파악과 튜닝을, 아니라면 ‘문제없어’를 확신하고 넘어갈 수 있다.
  2. testing 단계에서 GC flag를 켜는 것도 비용이 작다.
  3. memory profiler 설정은 비용이 크다.

heap 크기 조정 flag

flag operation
-Xms heap 최소 크기를 결정한다
-Xmx heap 최대 크기를 결정한다
-XX:MaxMetaspaceSize= metaspace의 최대 크기를 결정한다

튜닝 시 주의사항

  • GC flag를 추가/변경할 때는 한 flag씩 추가한다.
  • 각 flag가 무슨 작용을 하는지 알고 사용해야 한다.
  • 부수 효과를 일으키는 flag 조합이 있을수도 있다.

튜닝 주요 인자

  1. 할당
  2. 중단시간
  3. 처리율 추이
  4. 객체 수명

1. 할당

튜닝 뿐 아니라 성능 판단에 꼭 필요하다.
young generation GC event 데이터를 통해 할당된 데이터 양, 단위 수집 시간, 평균 할당률을 계산할 수 있다.

  • 수작업으로 할당률을 계산하는 것은 시간 낭비. 툴을 사용하자

2. 중단 시간

대부분의 application에서 100ms 정도의 중단은 무시할만하다.
중단 시간을 얼마나 허용할 수 있느냐를 기준으로 GC를 선택할 수 있다.

  • 일반적으로 중단시간이 1초 이상으로 커도 된다면 Parallel이 좋다.

reference

  • Optimizing Java, chapter8