JAVA 성능튜닝가이드

목차

  1. Tools
  2. Case Study
  3. Swap

1. Tools

jps

실행되고 있는 java의 프로세스번호를 확인할 때 사용된다.

반드시 java를 실행한 계정과 동일한 계정으로 jps를 실행한다. 예를 들어, root계정으로 java를 실행하고 sysadmin계정으로 jps를 실행할 경우 프로세스가 보이지 않는다.

jpsps -ef|grep java 와 비슷한 역할이다.

jstat

실행되고 있는 javagc등의 상태를 확인한다. 많이 사용되는 방법은 다음과 같다.

jstat -gc -h10 <JAVA PID> 1000 0

-gc는 garbage collection의 상태를 확인하는 것이고 -h10은 10줄마다 헤더를 출력하라는 것이고 1000은 1000ms마다 출력하라는 것이고 0은 무한반복을 뜻한다.

jstack

Thread가 현재 무엇을 하고 있는지 확인하고 싶다면 jstack을 사용한다.

jstack <JAVA PID>

또는

jstack <JAVA PID> > thread1.txt

와 같이 파일로 저장하고 확인한다.

2. Case Study

Stop-the-world Pause Detection

GC Pause중에 "stop-the-world" pause는 application을 수초에서 수분동안 정지시켜버린다. 아래는 jstat의 로그이다.

S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 14680064.0 39146880.0 32605668.0 36416.0 36387.0      3   36.295  395  10635.418 10671.712
2446656.0 2446656.0  0.0    0.0   14680064.0 351203.5 39146880.0 32605818.4 36416.0 36387.0      3   36.295  395  10662.559 10698.853

아래쪽 로그를 보면 OU 즉 Old Usage가 14680064.0으로 10초이상 줄어들지 않고 있다가 마지막에 줄어들면서 FGCT 즉 Full GC Time이 10635에서 10662로 약 27초 증가된것을 볼수 있다. 27초가량 application이 멈추고 Full GC가 진행된것이다.

해결책

GC멈춤문제를 해결하기 위해서는 JVM Tuning이 필요한데, 위의 상황에서는 Eden영역을 줄여서 Collector가 확인하는 Object의 량을 줄여줄수가 있을 것이다. Yong Generation영역은 Eden + Survivor 인데, jvm옵션으로 -XX:MaxNewSize=7g 와 같이 크기를 정해줄수 있다. Eden이 14G로 다소 크기 때문에 Young영역을 7G로 제한하면 약 6G가 할당될것이다. Colletor는 기존 14G의 Object를 살펴보는것에서 6G만 살펴보는 것으로 부담이 줄어든다.

3. Swap

Swap 메모리의 특성 상 물리 메모리에 비해 속도가 느리다. 따라서 지속적으로 메모리를 사용하는 검색엔진의 특성 상 스왑핑을 최소화하여야 한다. 일시적으로 스왑 메모리를 제거하려면 다음 명령어를 사용한다.

sudo swapoff -a

해당 명령어를 통해 모든 스왑 메모리의 해제가 가능하다. 다만 서버를 재부팅하면 OS의 기본 설정에 따라 스왑 메모리가 다시 잡힌다. 재부팅 후에도 스왑 메모리에 대한 설정을 유지하고자 한다면 swappiness 옵션을 설정해 주어야 한다. swappiness 옵션 확인은 다음 명령어들 중 하나를 입력할 시 확인 가능하다.

sysctl vm.swappiness
sysctl -a | grep swappiness
cat /proc/sys/vm/swappiness

swappiness의 기본 값은 60이며, 해당 명령들을 통해 swappiness 값의 변경 또한 가능하나 영구 적용을 위해서는 /etc/sysctl.conf 을 수정하여여 한다.

설명
vm.swappiness = 0 (커널 버전 3.5 이상) 스왑핑 끄기
vm.swappiness = 1 (커널 버전 3.5 이상) 스왑핑 최소화
vm.swappiness = 10 메모리가 충분할 때 성능향상을 위해 권장되는 경우가 있음
vm.swappiness = 60 기본값
vm.swappiness = 100 적극적으로 스왑 사용

vi 로 sysctl.confvm.swappiness을 추가한다. 아무 설정도 하지 않았다면 vm.swappiness는 설정되지 않은 상태이다. 추천하는 옵션은 vm.swappiness = 1으로서 스왑핑을 최소화한다.

vm.swappiness = 1

수정 후 서버를 재부팅하면 해당 옵션이 적용된다.