Post

자바 성능 튜닝 이야기 8주차

자바 성능 튜닝 이야기 8주차

들어가며

이 포스트는 이상민의 「자바 성능 튜닝 이야기」 Chpater18 ~ 20을 읽고 개인적으로 학습한 내용을 정리한 글입니다.

  • 책: 자바 성능 튜닝 이야기
  • 저자: 이상민
  • 출판사: 인사이트
  • 챕터: Chapter18 ~ Chapter 20

핵심 정리 내용

18장 GC가 어떻게 수행되고 있는지 보고 싶다

자바 인스턴스 확인을 위한 jps

  • jps 사용 방법
1
    jps [-q] [-mlvV] [-Joption] [<hostid>]
  • jps 명령 옵션
    • -q : 클래스나 JAR 파일명, 인수 등을 생략하고 내용을 타나낸다
    • -m : main 메서드에 지정한 인수들을 나타낸다
    • -l : 애플리케이션의 main 클래스나 애플리케이션 JAR 파일의 전체 경로 이름을 나타낸다
    • -v : JVM에 전달된 자바 옵션 목록을 나타낸다
    • -V : JVM의 플래그 파일을 통해 전달된 인수를 나타낸다
    • -Joption : 자바 옵션을 이 옵션 뒤에 지정할 수 있다

GC 상황을 확인하는 jstat

  • jstat 사용 방법
1
2
3
4
    jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

    // 실제 예시
    jstat -gcnew -t h10 2624 1000 20 > jstat_WAS1.log
  • jstat 명령 옵션
    • -t : 수행 시간을 표시한다
    • -h:lines : 각 열의 설명을 지정된 라인 주기로 표시한다
    • interval : 로그를 남기는 시간의 차이(ms)를 의미
    • count : 로그 남기는 횟수
  • option의 종류
    • class : 클래스 로더에 대한 통계
    • compiler : 핫스팟 JIT 컴파일러에 대한 통계
    • gc : GC 힙 영역에 대한 통계
    • gccapacity : 각 영역의 허용치와 연관된 영역에 대한 통계
    • gccause : GC의 요약 정보와 마지막 GC, 현재 GC에 대한 통계
    • gcnew : 각 영역에 대한 통계
    • gcnewcapacity : Young 영역과 관련된 영역에 대한 통계
    • gcold : Old와 Perm 영역에 대한 통계
    • gcoldcapacity : Old 영역의 크기에 대한 통계
    • gcpermcapacity : Perm 영역의 크기에 대한 통계
    • gcutil : GC에 대한 요약 정보
    • printcompilation : 핫 스팟 컴파일 메서드에 대한 통계

GC 튜닝할 때 가장 유용한 jstat 옵션은 두 개

1
2
   NGCMN        NGCMX         NGC          S0C     S1C              EC         OGCMN        OGCMX         OGC           OC         MCMN       MCMX        MC       CCSMN     CCSMX     CCSC     YGC    FGC   CGC
    0.0     524288.0     153600.0         0.0     10240.0     143360.0          0.0     524288.0     114688.0     114688.0        0.0   458752.0    98368.0       0.0  327680.0   13952.0     56     0    36
  • NGC로 시작하는 것
    • Young 영역의 크기 관련
  • OGC로 시작하는 것
    • Old 영역
  • PGC로 시작하는 것
    • Perm 영역
  • S0C, S1C, EC,OC,PC
    • Survivor0,Survivor1, Eden, Old, Perm
  • MN, MX,C로 끝나는 항목
    • Min, Max, Commited
  • FGC, CGC
    • Minor GC, Full GC
  • gcutil 옵션 ``` S0 S1 E O M CCS YGC YGCT FGC FGCT CGC CGCT GCT
    • 99.85 65.00 89.26 97.55 88.84 56 0.471 0 0.000 36 0.302 0.773
    • 99.85 65.00 89.26 97.55 88.84 56 0.471 0 0.000 36 0.302 0.773
    • 99.85 65.00 89.26 97.55 88.84 56 0.471 0 0.000 36 0.302 0.773
    • 99.85 65.00 89.26 97.55 88.84 56 0.471 0 0.000 36 0.302 0.773
    • 99.85 65.00 89.26 97.55 88.84 56 0.471 0 0.000 36 0.302 0.773 ```
  • S0, S1
    • Survivor 영역
  • E
    • Eden 영역
  • YGC : Young 영역의 GC 횟수
  • YGCT : Young 영역의 GC가 수행된 누적 시간
  • O : Old 영역
  • P : Perm 영역
    • 두 개 영역 중 하나라도 GC가 발생하면 FGC의 횟수 증가, FGCT 시간이 늘어남
  • GCT : Young GC가 수행된 시간인 YGCT 와 Full GC가 수행된 시간인 FGCT 의 합

원격으로 JVM 상황을 모니터링하기 위한 jstatd

1
    jstatd [-nr] [-p port] [-n rminname]
  • nr : RMI registry 가 존재하지 않을 경우 새로운 RMI 레지스트리를 jstatd 프로세스 내에서 시작하지 않는 것을 정의하기 위한 옵션
  • p : RMI 레지스트리를 식별하기 위한 포트 번호
  • n : RMI 객체의 이름을 지정한다. 기본 이름은 JStatRemoteHost

verbosegc 옵션을 이용하여 gc 로그 남기기

PrintGCTimeStamps 옵션

  • XX:+PrintGCTimeStamps
    • 좌측에 수행한 시간이 포함

PrintHeapAtGC 옵션

  • XX:+PrintHeapAtGC
    • GC의 더 많은 정보를 볼 수 있음

PrintGCDetails

  • XX:+PrintGCDetails
    • GC의 더 많은 정보를 볼 수 있음
  • 다른 분석 툴
    • GC Analyzer
      • sun에서 제공하는 GC 분석 툴
      • 펄 스크립트 기반의 분석 결과
    • IBM GC 분석기
    • HPjtune

19장 GC 튜닝을 항상 할 필요는 없다

GC 튜닝을 꼭 해야 할까?

  • Java 기반의 모든 서비스에서 GC 튜닝을 진행할 필요는 없다 - 아래의 설정이 있을 경우
    • -Xms 옵션과 -Xmx 옵션으로 메모리 크기를 지정
    • -server 옵션이 포함되어 있다
  • JVM의 메모리 크기도 지정하지 않았고, Timeout이 지속적으로 발생하고 있다면 GC 튜닝을 하는 것이 좋다
  • GC 튜닝은 가장 마지막에 하는 작업
  • GC는 생성된 객체를 제거 > 객체가 많이 생성될 수록 GC를 수행하는 횟수도 증가 > 즉 객체 생성을 줄이는 작업을 먼저 해야한다

Old 영역으로 넘어가는 객체의 수 최소화하기

  • Old 영역의 GC는 New 영역의 GC에 비해 상대적으로 시간이 오래 소요
  • Old 영역으로 이동하는 객체의 수를 줄이면 Full GC가 발생하는 빈도를 많이 줄일 수 있다

Full GC 시간 줄이기

  • Full GC는 Young GC에 비해 실행 시간이 길기 때문에 Full GC 실행에 시간이 오래 소요되면 연계된 여러 부분에서 타임아웃 발생할 수 있음
  • 그렇다고 Full GC 실행 시간을 줄이기 위해 Old 영역의 크기를 줄이면 OOM이 발생하거나 Full GC 횟수가 증가
  • 반대로 Old 영역의 크기를 늘리면 Full GC 횟수는 줄어들지만 실행 시간이 늘어난다
  • Old 영역의 크기를 적절하게 ‘잘’ 설정해야 한다

GC의 성능을 결정하는 옵션들

  • Heap 영역 크기
    • -Xms : JVM 시작 시 힙 영역 크기
    • -Xmx : 최대 힙 영역 크기
  • New 영역의 크기
    • -XX:NewRatio : New 영역과 Old 영역의 비율
    • -XX:NewSize : New 영역의 크기
    • -XX:SurvivorRatio : Eden 영역과 Survivor 영역의 비율
  • -Xms, -Xmx는 필수-XX:NewRatio 옵션을 어떻게 설정하느냐에 따라 GC 성능에 많이 차이 발생
  • GC 방식에 따라 지정할 수 있는 옵션
    • Serial GC : -XX:+UseSerialGC
    • Parallel GC : -XX:+UseParallelGC, -XX:ParallelGCThreads=value
    • Parallel Compacting GC : -XX:+UseParallelOldGC
    • CMS GC : -XX:+UseConcMarkSweepGC, -XX:+UseParNewGC, -XX:+CMSPArallelRemarkEnabled, -XX:+CMSInitiatingOccupancyFraction=value, -XX:+UseCMSInitiatingOccupancyOnly
    • G1 : -XX:+UnlockExperimentalVMOptions, -XX:+UseG1GC

GC 튜닝의 절차

  1. GC 상황 모니터링
    • GC 상황을 모니터링 하면서 현재 운영되는 시스템의 GC 상황을 확인
  2. 모니터링 결과 분석 후 GC 튜닝 여부 결정
    • GC 상황 확인 후, 결과를 분석하고 GC 튜닝 여부를 결정
    • GC 수행에 소요된 시간이 0.1 ~ 0.3 초 밖에 안된다면 굳이 GC 튜닝에 시간을 낭비할 필요는 없다
    • GC 수행 시간이 1~3초, 심지어 10초가 넘는 상황이라면 GC 튜닝 진행 필요
  3. GC 방식/메모리 크기 지정
    • GC 방식 결정 및 메모리 크기 지정
  4. 결과 분석
    • GC 옵션을 지정하고 적어도 24시간 이상 데이터를 수집한 후 분석을 실시
  5. 결과가 만족스러울 경우 전체 서버에 반영 및 종료

1, 2단계: GC 상황 모니터링 및 결과 분석하기

1
2
3
4
5
6
  S0     S1     E      O      M     CCS    YGC     YGCT     FGC    FGCT     CGC    CGCT       GCT
     -  99.85  65.00  89.26  97.55  88.84     56     0.471     0     0.000    36     0.302     0.773
     -  99.85  65.00  89.26  97.55  88.84     56     0.471     0     0.000    36     0.302     0.773
     -  99.85  65.00  89.26  97.55  88.84     56     0.471     0     0.000    36     0.302     0.773
     -  99.85  65.00  89.26  97.55  88.84     56     0.471     0     0.000    36     0.302     0.773
     -  99.85  65.00  89.26  97.55  88.84     56     0.471     0     0.000    36     0.302     0.773
  • 데이터 보는 순서
    1. YGC와 YGCT의 값을 확인
      • YGCT 나누기 YGC > 해당 값을 비교
    2. FGCT와 FGC의 값을 확인
      • FGCT / FGC
  • GC 튜닝이 필요 없는 수준
    • Minor GC의 처리 시간이 50ms 내외
    • Minor GC 주기가 빈번 (10초 내외)
    • Full GC 처리 시간이 1초 이내
    • Full GC 주기가 10분에 1회
    • GC 수행 횟수도 확인해봐야함

3-1단계: GC 방식 지정

  • Concurrent mode failure에 대해서 좀 더 알아보자
  • Parallel GC와 CMS GC의 큰 차이점은 압축 작업 여부
    • 압축은 메모리 할당 공간 사이에 사용하지 않는 빈 공간이 없도록 옮겨서 메모리 단편화를 제거하는 작업
  • Parallel GC
    • Full GC가 수행될 때마다 압축 작업을 진행해 시간이 많이 소요
    • Full GC 수행 이후 메모리르 연속적으로 지정해 메모리를 더 빠르게 할당 가능
  • CMS GC
    • 압축 작업을 수행하지 않아 속도가 빠름
    • 메모리 단편화 발생

3-2 단계 : 메모리 크기

  • 메모리 크기가 크면
    • GC 발생 횟수는 감소
    • GC 수행 시간은 길어짐
  • 메모리 크기가 작으면
    • GC 발생 횟수는 짧아짐
    • GC 수행 시간은 증가
  • 필자 추천
    • WAS 메모리를 500mb
    • NewRatio
      • XX+:NewRatio 1 > Old : new 영역 이 1:1

4단계: GC튜닝 결과 분석

  • 분석 시 살펴보아야하는 값
    • Full GC 수행 시간
    • Minor GC 수행 시간
    • Full GC 수행 간격
    • Minor GC 수행 간격
    • 전체 Full GC 수행 시간
    • 전체 Minor GC 수행 시간
    • 전체 GC 수행 시간
    • Full GC 수행 횟수
    • Minor GC 수행 횟수

20장 모니터링 API인 JMX

  • JMX 아키텍처 컴포넌트 사이의 관계 alt text

  • JMX의 4단계 레벨
    • instrumentation Level
    • Agent Level
    • Distributed Services Level
    • Additional Management Protocol APIs
  • instrumentation Level
    • 하나 이상의 MBean(Management Beans)를 제공
    • MBeans에서 필요한 리소스들의 정보를 취합해 에이전트로 전달하는 역할
  • Agent Level
    • 에이전트를 구현하기 위한 스펙이 제공되어 있음
    • 에이전트는 리소스를 관맇나느 역할
    • 에이전트는 모니터링이 되는 서버와 같은 장비에 위치
    • 에이전트는 MBean 서버와 MBeans를 관리하는 서비스의 집합으로 구성
  • Distributed Services Level
    • JMX 관리자를 구현하기 위한 인터페이스와 컴포넌트를 제공
    • 여러 에이전트에서 제공하는 정보를 관리할 수 있는 화면과 같은 부분 담당

MBean에 대해서 조금만 더 자세히 알아보자

  • MBean의 종류와 사용 용도
    • 표준 MBean(standard MBean) : 변경이 많지 않은 시스템을 관리하기 위한 MBean이 필요한 경우 사용
    • 동적 MBean(Dynamic MBean) : 애플리케이션이 자주 변경되는 시스템을 관리하기 위한 MBean이 필요한 경우 사용
    • 모델 MBean(Model MBean) : 어떤 리소스나 동적으로 설치 가능한 MBean이 필요한 경우 사용
    • 오픈 MBean(Open MBean) : 실행 중에 발견되는 객체의 정보를 확인하기 위한 MBean이 필요할 때 사용, JMX의 스펙에 지정된 타입만 리턴
  • 에이전트가 제공하는 기능
    • MBean의 속성값을 얻고, 변경한다
    • MBean의 메서드를 수행
    • 모든 MBean에서 수행된 정보를 받는다
    • 기존 클래스나 새로 다운로드된 클래스의 새로운 MBean을 초기화하고 등록
    • 기존 MBean들의 구현과 관련된 관리 정책을 처리하기 위해 에이전트 서비스를 사용되도록한다

Visual VM을 통한 JMX 모니터링

This post is licensed under CC BY 4.0 by the author.