237
Java Performance Tuning Certified Partner by

Java Performance Tuning

Embed Size (px)

Citation preview

Page 1: Java Performance Tuning

Java Performance Tuning

Certified Partner by

Page 2: Java Performance Tuning

2 - Internal Use Only -

회사 소개

오픈소스 컨설팅은 오픈 소스에 전문적인 컨설팅 기업으로써 Technical

Architect/Application Architect 컨설팅, 클라우드 관련 솔루션을 제공하고 있으며, 레드햇과

같은 오픈소스 벤더의 솔루션의 기술지원 사업을 수행합니다.

오픈소스 컨설팅은 오픈소스 운영체제/웹서버/미들웨어를 전문적으로 지원

하는 회사입니다. 또한 시스템 인프라, 개발 인프라를 위한 TA/AA에 대한

컨설팅 서비스를 지원하고 있으며, Athena 제품군을 보유하고 있습니다.

Solution

• Athena SQS

• Athena Provisioning

• Athena Monitoring

• Other Solution Frameworks

Consulting

• 시스템 아키텍처 컨설팅

• Amazon AWS 컨설팅

• Technical/Application Architect

• Middleware/Linux Dedicated Engineer

Technical Support

• Red Hat Linux, Virtualization

• Red Hat JBoss Middleware

• Apache Web Server, Tomcat

• MySQL/MariaDB/Percona

컨설팅 영역 오픈소스 기술지원

솔루션 영역

Page 3: Java Performance Tuning

3 - Internal Use Only -

강사 소개

Page 4: Java Performance Tuning

4 - Internal Use Only -

교육 목적

본 과정의 목적

• 미들웨어 운영자 관점에서 JVM 의 기본적인 동작 방식 및

튜닝에 필요한 기본 지식을 습득할 수 있음

• 기본 지식을 바탕으로 실제 운영에서 적용할 수 있는 성능

튜닝 방법을 교육

• 다양한 Tool 을 이용하여 전체적인 시스템 관점에서 JVM

레벨 까지 모니터링 할 수 있는 방법을 교육

Page 5: Java Performance Tuning

5 - Internal Use Only -

교육 내용

오전 – JVM Overall

• Performance tuning tactics

• Java Performance Tuning

• System Monitoring and Hotspot Tuning

오후 – Middleware on JVM

• Middleware Tuning 개요

• Troubleshooting

Page 6: Java Performance Tuning

Certified Partner by

Performance Tuning Tactics

Page 7: Java Performance Tuning

7 - Internal Use Only -

“데이터를 수집하기 전에 이론을

세우는 것은 중대한 실수다”

- 셜록 홈즈

Page 8: Java Performance Tuning

8 - Internal Use Only -

Performance Tuning Tactics

Performance Tuning 주관적이다? • Performance Issue 가 있는지 없는지 무슨 기준으로

판단할까?

• 빠르면 빠를 수록 좋다? (X)

• Performance tuning 은 객관적이어야 한다.

• 즉 baseline 성능 결과를 바탕으로 명확한 성능 target 이

있어야 한다. Target 이 없는 tuning 은 무의미 하다.

Page 9: Java Performance Tuning

9 - Internal Use Only -

Performance Tuning Tactics

Performance Tuning 순환 4단계

Baseline 구성

Performance

Tuning

데이터 수집

STEP 1

결과 분석

STEP 2

환경 설정

STEP 3

테스트 및 결과

STEP 4

Page 10: Java Performance Tuning

10 - Internal Use Only -

Performance Tuning Tactics

Performance Tuning 순환 6단계

애플리케이션 수정

솔루션 검토 (해결책)

성능 테스트 모니터링

데이터 수집

planning execution 병목 구간 확인

솔루션 적용

optional

Page 11: Java Performance Tuning

11 - Internal Use Only -

Performance Tuning Tactics

기준치(Baseline) 산정 • Tuning Target 의 기준이 됨

• 성능 목표

• 응답 시간(Response Time), 처리량(Throughput), 리소스 사용

(Resource Utilization) 목표 설정

• 점검 리소스 사용량 : CPU, Memory, Disk I/O, Network I/O

• 테스트 계획 및 테스트 스크립트

• 로드 테스트 시 필요한 일정 산정 및 스크립트 구성

• 로드 테스트용 도구 선정

• 점검 기준표 작성

• 시스템, 플랫폼, 애플리케이션에 대한 점검 매트릭스 사전 작성

• 성능 튜닝 프로세스에 대한 일지 기록

Page 12: Java Performance Tuning

12 - Internal Use Only -

Performance Tuning Tactics

AS-IS 운영 축적 자료를 통한 용량 산정

AS-IS 시스템( XXX사 XXX 장비, OOO tpmC) 일일 총 트랜잭션 : 43,200,000 건 동시 단말 : 8 Robot Agent 평균 초당 트랜잭션 : 500 Request/Sec CPU 사용률: 70%

예 1> A업체 생산 시스템

AS-IS 시스템( XXX사 XXX 장비, OOO tpmC) 일일 총 방문자: 46,293명 Peak 동시 단말사용자: 1000명 일일 총 호출건수 : 1,795,867건 Peak Arrival Rate : 182.5 tps Request Interval : 13.7 sec Visit time: 6분 25초 한 사용자당 총 호출횟수: 23회 CPU 사용률: 70%, 메모리 사용 : 1.6G

예 2> B 업체 인터넷 시스템

Page 13: Java Performance Tuning

13 - Internal Use Only -

Performance Tuning Tactics

TO-BE 목표 성능 지표 산정(예시)

Total Resources WAS : 3,040,000 tpmC DB : 1,600,000 tpmC

품 질 속 성 기 준 목 표 치 비 고

수행 내용

최대 TPS 성능 테스트 ( 3,040,000 / 1,680 = 1,809.7Tps) 1,809 TPS 이상 2009.06.28 기준 1,809Tps

최대 응답시간 (솔루션 처리 시간 (IN + OUT)) < 3 Sec주1) 업무의 복잡도, 대상 시스템(데이터 베이스, 타 시스템) 처리시간

안정성 테스트

- 24 hours 이상 주2)

실패 거래 None

시스템 충돌 No 상세 시나리오의 체크 리스트를 작성하여 결과를 확인

메모리 누수 현상 No 상동

확장성 테스트

시스템용량을 25% 에서 50%, 75%, 100%로 확장하는 테스트 주3)

확장에 따른 성능 증가를 보여주는 방법

Graph

확장에 따른 성능의 표준 편차 범위

~5 %

확장에 따른 응답시간의 표준 편차 범위

~0.05 sec

주1) 처리시간은 타겟 시스템으로 송,수신처리에 대한 연계 총 처리시간 임.

주2) 일일 영업시간 (8시간)을 기준으로 산정함.

주3) 시스템의 수를 1(전체 대비 25%)에서 2 (전체 대비 50%), 3 (전체 대비 75%), 4 (전체 대비 100%) 로 증가시켜 시스템 확장성을 테스트

Page 14: Java Performance Tuning

14 - Internal Use Only -

Performance Tuning Tactics

테스트 일정 도출

일 자 주요 Activity 세부 Activity

2013.00.00 시스템 설치

시스템 Setup - H/W, S/W, Middleware, DBMS, 통신환경구축 등

상세 테스트 시나리오 준비

대상 프로젝트 적용시 예상 거래 테스트 케이스

안정성 테스트 케이스

테스트를 위한 데이터 수집

Load Runner Script 준비

2013. 00. 00 ~ 2013.00. 00

시스템 환경 점검

성능/부하 테스트 및 결과 데이터 수집

테스트 수행

시스템 내부 Configuration Setup 및 튜닝

L4, WAS 서버 튜닝

DBMS 서버 튜닝

시스템 파라미터 튜닝

시나리오상의 업무들의 사전 테스트 실시

Memory Leak & Garbage Collection Optimizing

시나리오에 따른 성능/부하 테스트 진행

테스트 및 결과 자료 수집

2013. 00. 00 결과 보고서 작성 테스트 결과 자료에 대한 분석 및 평가

Page 15: Java Performance Tuning

15 - Internal Use Only -

Performance Tuning Tactics

테스트 일정 상세 도출

날 짜 시간 작업 내용 담당 비 고

6/26(금) 17:30 -

- 시스템 입고

- p595, superdome, E10000 * 1EA, E4900 * 1EA, ST9990, NT Rack * 1EA

H/W 벤더

6/27(토) 09:00 -

- O/S Install 및 config 구성

- JDK 1.6 최신 Version Install, C compiler Install

- Network 연결 및 설정

H/W 벤더

H/W 벤더

BMT 시행사

IP정보

6/28(일) 09:00 - - DISK 구성 H/W 벤더 전원확보

6/29(월) 09:00 -

- Database Engine Install (클러스터 구성)

- WAS Engine Install

- Web Server Install

- Rule Engine Install

DB 벤더

M/W 벤더

BMT 시행사

DB Table 정보

6/30(화) 09:00 - - BMT 애플리케이션 세팅 BMT 시행사

7/1(수) 09:00 - - 구성 점검

7/2(목)

7/3(금) 09:00 - - DB Table 구성 확인 및 구성 점검

7/4(토) - BMT 시나리오 설명회 BMT 시행사

7/6(월)~7/31(금) - BMT 시나리오 수행 ALL

Page 16: Java Performance Tuning

16 - Internal Use Only -

Performance Tuning Tactics

파일럿 애플리케이션 추출

• 전체 기반 성능 테스트를 할 경우 모두를 테스트할 수는 없다.

• 상위 트랜잭션의 80%를 차지하는 10~20%의 애플리케이션을 추출

• 애플리케이션 트랜잭션의 경우 대부분 파레토(Pareto, 80 vs 20) 법칙이 적용.

Page 17: Java Performance Tuning

17 - Internal Use Only -

Performance Tuning Tactics

Bench Mark Test 진행

• 조건

같은 워크 로드

같은 테스트 스크립트

같은 부하 생성 서버

모든 테스트 환경이 동일해야 함.

• 변경 가능 항목

시스템 파라미터

JVM 파라미터

애플리케이션 서버 인스턴스

동일한 부하를 줄 수 있는 Machine Gun 선택

Page 18: Java Performance Tuning

18 - Internal Use Only -

Performance Tuning Tactics

BMT를 통한 튜닝 접근법

• 관련된 모든 수치를 최대한 높인 후, 점차적으로 Active Thread 수를 증가시

키며 테스트를 시행하고, 그 결과를 반드시 TPS그래프로 그리거나 툴을 이

용.

• 각 Tier 혹은 머신의 CPU/MEM, 네트워크, 응용 애플리케이션이 사용하는

TCP/IP port를 모니터링하고, 각 구간의 Saturation Point를 찾아라.

• 가급적 백엔드(Backend)시스템의 Saturation Point부터 찾아야 한다.

• 가장 먼저 Bottle-neck으로 도출되는 구간부터 튜닝하라.

• 다시 Active thread 수를 증가시키며 동일한 테스트를 반복 시행하고 TPS의

전체적인 그래프를 통해 성능상의 변화를 확인하라. 이 과정은 계속 반복되

어야 한다. <자바 서비스넷 이원영 대표>

Page 19: Java Performance Tuning

19 - Internal Use Only -

Performance Tuning Tactics

성능 측정 툴

• HP LoadRunner

• SOAP UI - http://www.soapui.org/

• Apache Bench

• Apache Jmeter - http://jmeter.apache.org/

Page 20: Java Performance Tuning

20 - Internal Use Only -

Performance Tuning Tactics

Apache Bench

• Option

Usage: ab [options] [http[s]://]hostname[:port]/path

Options are:

-n requests Number of requests to perform

-c concurrency Number of multiple requests to make

-t timelimit Seconds to max. wait for responses

-b windowsize Size of TCP send/receive buffer, in bytes

-C attribute Add cookie, eg. 'Apache=1234. (repeatable)

-A attribute Add Basic WWW Authentication, the attributes

are a colon separated username and password.

-k Use HTTP KeepAlive feature

Page 21: Java Performance Tuning

21 - Internal Use Only -

Performance Tuning Tactics

Apache Bench

• 테스트

ab -n 10000 -c http://10.64.160.179:8080/test.jsp

동시 사용자 10명이 총 1000번의 요청을 날린다. (각각 10000번이 아님)

• 결과

Server Software: Apache-Coyote/1.1 Server Hostname: 10.64.160.179 Server Port: 8080 Document Path: /test.jsp Document Length: 1543 bytes Concurrency Level: 10 Time taken for tests: 2.700 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 18856956 bytes HTML transferred: 15443887 bytes Requests per second: 3703.10 [#/sec] (mean) Time per request: 2.700 [ms] (mean) Time per request: 0.270 [ms] (mean, across all concurrent requests) Transfer rate: 6819.26 [Kbytes/sec] received

Page 22: Java Performance Tuning

22 - Internal Use Only -

Performance Tuning Tactics

성능 측정 기록

Test Date 시나리오 AP Server 시나리오 Time WAS

인스턴스수 Total Users TPS 응답시간 CPU CPU MAX

2013.06.17 TC1-1(a) AP1 TC1-1 10m 1 30 410.258 0.072 63.39 69.00

TC1-1(b) TC1-2(a)

TC1-1 10m 1 30 241.460 0.118 23.15 24.00

TC1-2(b) TC2-1 10m 2 60 433.651 0.132 45.00 48.00

TC1-2© TC2-1 10m 3 90 618.593 0.135 66.26 71.00

TC1-2(d) TC2-1 10m 4 120 814.038 0.144 89.31 94.00

TC1-2(e) TC2-1 10m 5 150 817.087 0.175 92.21 96.00

TC1-2(f) TC2-1 10m 6 180 836.576 0.207 94.31 96.85

2013.06.17 TC3-1(a) AP3 TC3-1 10m 1 40 518.266 0.073 83.35 89.00

TC3-1(b) TC3-2(a)

TC3-1 10m 1 40 196.311 0.195 24.34 25.00

TC3-2(b) TC3-2 10m 2 80 353.730 0.218 47.36 50.00

TC3-2© TC3-2 10m 3 120 522.938 0.223 72.27 75.00

TC3-2(d) TC3-2 10m 4 160 669.803 0.230 94.24 98.00

2013.06.17 TC5-1(a) AP5 TC5-1 10m 1 40 502.639 0.075 83.83 89.00

TC5-1(b) TC5-2(a)

TC5-1 10m 1 40 183.560 0.210 24.53 26.00

TC5-2(b) TC5-2 10m 2 80 328.652 0.233 47.63 50.00

TC5-2© TC5-2 10m 3 120 472.794 0.244 71.51 74.00

TC5-2(d) TC5-2 10m 4 160 621.968 0.249 94.92 98.00

Page 23: Java Performance Tuning

23 - Internal Use Only -

Performance Tuning Tactics

테스트 결과 분석

Page 24: Java Performance Tuning

Certified Partner by

Java Performance Tuning

Page 25: Java Performance Tuning

Throughput vs Latency

Page 26: Java Performance Tuning

26 - Internal Use Only -

Java Performance Tuning

Throughput

Page 27: Java Performance Tuning

27 - Internal Use Only -

Java Performance Tuning

Latency

Page 28: Java Performance Tuning

28 - Internal Use Only -

Java Performance Tuning

Latency(Response Time) vs Throughput

Page 29: Java Performance Tuning

29 - Internal Use Only -

Java Performance Tuning

“5초의 Latency 향상으로 25%의 Page View 향상, 10% 매출 증가, 50%의 하드웨어 절약”

“100ms latency delay 마다 %1 의 매출 감소”

0.5초의 latency delay 마다 20% 의 traffic 감소

Page 30: Java Performance Tuning

30 - Internal Use Only -

Java Performance Tuning

Page 31: Java Performance Tuning

31 - Internal Use Only -

Java Performance Tuning

Tuning 에서 무엇 보다 중요한 요소

I don't know what I don't know I know what I don't know I already know what I need to know

Page 32: Java Performance Tuning

32 - Internal Use Only -

Java Performance Tuning

복잡한 시스템에서의 performance

• 현대의 시스템은 매우 복잡하다.

• OS/ Kernel / Processor

• DNS, TCP, Webserver, network link

• Backend 시스템, DB, Legacy system 등등

• Front End

• Messaging Latency

• Packet retransmission, batching(nagle’s algorithm),

CPU scheduling, network queue 등등

Page 33: Java Performance Tuning

33 - Internal Use Only -

Java Performance Tuning

Java Performance Tuning Iterative Process

Page 34: Java Performance Tuning

34 - Internal Use Only -

Java Performance Tuning

• Memory Footprint

• Startup Time

• Throughput

• Transaction Per second (TPS)

• Latency

셋 중에 최대 2개만 선택 가능

Minimize Memory Footprint

Minimize GC Paus

es

Minimize GC Over

head

Page 35: Java Performance Tuning

35 - Internal Use Only -

Java Performance Tuning

• Java Performance Equation

C * R * T = F(고정 값)

• C : Compactness 즉 Footprint

• R : Responsiveness 즉 Latency

• T : Throughput

• 튜닝이란, 고정 값 F 를 위해 C, R, T 를 조정하는 작업

• 최적화를 통해 F 값을 증가

Page 36: Java Performance Tuning

Java Performance Modern Trend

Page 37: Java Performance Tuning

37 - Internal Use Only -

Java Performance Modern Trend - Memory

• Latency 에 가장 큰 영향을 미치는 GC

• Memory Footprint

• Session Data 등에 In memory Session Grid 사용

• Oracle Coherence 등 Jboss Infinispan

• OSC 돌리

• Heap 사용을 최소화(sun.misc.Unsafe)

• Non Heap 기반 framework

• LMAX Disruptor

Page 38: Java Performance Tuning

38 - Internal Use Only -

Java Performance Modern Trend – I/O

• Asynchronous I/O Framework

• 대표적인 Framework

• Netty

• Spring Reactor

• Play Framework(based on Netty)

• Async Servlet – Servlet 3.0

Page 39: Java Performance Tuning

39 - Internal Use Only -

Java Performance Modern Trend – Lock Contention

• Lock 이 주는 영향

• Involuntary Context Switch

• CPU pipeline 훼손

• Lock 은 기본적으로 비싼 CPU Operation

Page 40: Java Performance Tuning

40 - Internal Use Only -

Java Performance Modern Trend – Lock Contention

• Java 8 에 StampedLock

• ReentrantLock 에 Optimistic Read 향상

• Lock Free 알고리즘

• Single Writer Principle

• Disruptor

• Brian Goetz “이런 일은 전문가에게 맡기세요”

Page 41: Java Performance Tuning

41 - Internal Use Only -

Java Performance Modern Trend – Lock Contention

Page 42: Java Performance Tuning

System Monitoring Overview

Page 43: Java Performance Tuning

43 - Internal Use Only -

System Architecture (Linux vs Solaris)

출처 : What Linux can learn from Solaris performance and vice-versa

Page 44: Java Performance Tuning

44 - Internal Use Only -

System Architecture – Linux layer 별 Monitoring Tool

출처 : What Linux can learn from Solaris performance and vice-versa

Page 45: Java Performance Tuning

45 - Internal Use Only -

System Architecture

System 의 각 layer 별로 Monitoring Tool 이 존재

• 공통적으로 제공하는 tool

• vmstat, mpstat, sar, netstat, nmon 등등

• 각 OS 별로 특화되는 Tool

• HP-UX : glance 등

• IBM : monitor, nmon(Linux) 등

• Solaris : prstat 등

• 모니터링 하고자 하는 layer 를 정확하게 파악하고 OS 에

따라 그에 맞는 Tool 을 사용 하는 것이 중요

Page 46: Java Performance Tuning

46 - Internal Use Only -

System Architecture

Java Monitoring 을 위한 중요 Monitoring 항목

• CPU

• CPU 사용률

• 프로세스 별 CPU 사용량

• CPU Contention (경합)

• Network I/O

• Disk I/O

• Virtual memory

Page 47: Java Performance Tuning

System Monitoring

Page 48: Java Performance Tuning

48 - Internal Use Only -

System Monitoring - CPU

CPU Monitoring 의 의미 • 시스템에 운용 중인 application 들에 CPU demand 를 파악

• 각각의 application 들이 사용 중인(thread 레벨까지) CPU

사용량을 파악

• CPU Usage

• User time

• System time

• Wait time

• Context Switch

• vmstat 을 이용한 monitoring 이 가장 기본적이고 일반적인

방법

Page 49: Java Performance Tuning

49 - Internal Use Only -

System Monitoring – CPU - vmstat

• User time (us) : 어플리케이션이 사용중인 전체 CPU 사용률

• System time (sy) : 커널과 관련된 CPU 사용률

• Idle time (id) : Idle 한 CPU

• 대부분의 OS 에 vmstat 결과에서 cpu 관련 내용은 동일 함.

Page 50: Java Performance Tuning

50 - Internal Use Only -

System Monitoring – CPU - vmstat

vmstat • CPU idle 이 10% 미만인 경우 주의

• procs 의 r 값

• Linux 의 경우 r 값은 현재 실행중인 task + 대기중인

task 이므로 이 현재 CPU count 보다 대략 2배 이상

높은 경우 CPU 부족을 의미

• Solaris 의 경우는 단순 대기 task 의 개수 이므로 CPU

count 보다 높은 경우 CPU 부족을 의미

• swap 이 일어 나고 있는지 확인

Page 51: Java Performance Tuning

51 - Internal Use Only -

System Monitoring – CPU - context switch

Context switch

• 각 thread 는 CPU 에 의해 주어진 time slice 만큼만 CPU 를

활용 가능

• Voluntary CS: 정해진 시간 안에 operation 을 끝내고 I/O

를 기다릴 때 혹은 lock

• Involuntary CS: 정해진 시간 안에 operation 을 끝내지

못해서 다른 thread 에 강제로 control 이 옮겨짐

• L1 cache : 3cycle, main memory 240cycle

Page 52: Java Performance Tuning

52 - Internal Use Only -

System Monitoring – CPU - context switch

Context switch

• Context Switch/voluntary context switch 비율이 3~5%이면

과도하다고 판단

• Lock contention

• Solaris : mpstat, Linux : pidstat -w

• Involuntary context switch

• CPU Binding

• Application thread 개수 줄임

Page 53: Java Performance Tuning

53 - Internal Use Only -

System Monitoring – CPU - mpstat

• 각 OS 마다 mpstat 의 결과는 다름 (위 화면은 Linux)

• CPU 사용률이 balanced 가 되지 않는 경우 application 에

multi thread 효율성이 떨어진다고 볼 수 있음 – Pinning?

Page 54: Java Performance Tuning

54 - Internal Use Only -

System Monitoring – Network

• 네트워크 병목 확인

• 전송 속도 - Ideal 한 최대 속도

• Ethernet 1Gbps – 125MBps

• Ethernet 10Gbps – 1.25GBps

• Infiniband 40Gbps – 5GBps

• 100Mbps급: 실 전송속도의 60%라고 한다면

실 전송속도 60Mbps = 60*1024(Kbps) = 60*1024/8(KB/sec)

= 7680(KB/sec)

• 10K data전송 : 7680(KB/sec) / 10(KB) = 760.8 TPS

• 100K data 전송 : 7680(KB/sec) / 100(KB) = 70.68 TPS

Page 55: Java Performance Tuning

55 - Internal Use Only -

System Monitoring – Network- nethogs

• Nethogs – Process 별 network 사용량 monitoring

Page 56: Java Performance Tuning

56 - Internal Use Only -

System Monitoring – Virtual Memory

• Virtual Memory Monitoring 항목

– Swap in

– Swap out

• System Swapping 은 Java Performance 에 큰 악영향

• -XX:+AlwaysPreTouch – Linux 는 Process Page 를 Dynamic 하게 할당함.

– Solaris 는 Process 기동시에 Memory 를 전부 할당

Page 57: Java Performance Tuning

57 - Internal Use Only -

System Monitoring – Disk I/O

• iostat –xm

• system, 특히 iowait 을 주의깊게 살펴 본다.

Page 58: Java Performance Tuning

Garbage Collection

Page 59: Java Performance Tuning

59 - Internal Use Only -

JVM 기본 – Hotspot Heap 구조

Page 60: Java Performance Tuning

60 - Internal Use Only -

JVM 기본 – IBM Heap

Page 61: Java Performance Tuning

61 - Internal Use Only -

JVM 기본 – Adaptive Memory Management

• “Ergonomics”

• Generation Size, Heap Size, GC Thread 개수 등을 시스템에 따라 자동으로 지정

• Heap usage 와 GC 통계를 이용하여 자동으로 heap size 등을 자동으로 조정

– Survivor Space

• ParallelOldGC 의 경우 UseAdaptiveSizePolicy 가 기본으로 enable

• Size 가 바뀔때 마다 GC latency 증가

Page 62: Java Performance Tuning

62 - Internal Use Only -

GC 의 기본 – Generational Collection

Page 63: Java Performance Tuning

63 - Internal Use Only -

GC 의 기본 – Generational Collection

Page 64: Java Performance Tuning

64 - Internal Use Only -

Hotspot Internal

Page 65: Java Performance Tuning

65 - Internal Use Only -

Eden S0 S1

Hotspot Internal – Life of Object

Page 66: Java Performance Tuning

66 - Internal Use Only -

0

Number indicates Age

Hotspot Internal – Life of Object

Page 67: Java Performance Tuning

67 - Internal Use Only -

1

Hotspot Internal – Life of Object

Page 68: Java Performance Tuning

68 - Internal Use Only -

2

Hotspot Internal – Life of Object

Page 69: Java Performance Tuning

69 - Internal Use Only -

3

Hotspot Internal – Life of Object

Page 70: Java Performance Tuning

70 - Internal Use Only -

4

Hotspot Internal – Life of Object

Page 71: Java Performance Tuning

71 - Internal Use Only -

5

Hotspot Internal – Life of Object

Page 72: Java Performance Tuning

72 - Internal Use Only -

Hotspot Internal – Life of Object

Page 73: Java Performance Tuning

73 - Internal Use Only -

GC Tuning 기본 원칙

• 최대한 단순하게 시작

• Throughput vs Latency Collector 선택

• Production 에서도 GC Logging 은 항상 enable 할 것

• 일반적으로 GC Pause 의 5% 미만의 overhead

• -verbose:gc

• -XX:+PrintGCDetails, -XX:+PrintGCDateStamps

• -Xloggc:<File>

Page 74: Java Performance Tuning

74 - Internal Use Only -

Hotspot Collector – Young Collection

• ‘Minor’ Collection

• Stop-The-World GC

• 아주 빠르고 효율적임

• 정해진 횟수 이상 GC 를 견뎌낸 Object 들은 Old Generation 으로 Promotion

• GC Collector 종류

– ParallelGC (+XX:UserParallelGC)

– ParNewGC (+XX:ParNewGC)

Page 75: Java Performance Tuning

75 - Internal Use Only -

Hotspot Collector – Old Collection

• ‘Major’ Collection

• Stop-The-World GC

• Fragmented 된 Heap 의 Compaction 을 위해 “Full GC” 필요

• GC Collector 종류

• Serial Old

• Java 7 부터 기본 collector 는 ParallelOldGC

• ParallelOld (-XX:+UseParallelOldGC)

• Concurrent

• (-XX:+UseConcMarkSweepGC)

• Java 7 U4+ 부터 G1 GC

Page 76: Java Performance Tuning

76 - Internal Use Only -

Hotspot Collector – Old Collection

-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseConcMarkSweepGC

Page 77: Java Performance Tuning

77 - Internal Use Only -

Hotspot Collector – Combination

Page 78: Java Performance Tuning

78 - Internal Use Only -

Hotspot Collector – Recommended Combination

Page 79: Java Performance Tuning

G1 Collector 소개

Page 80: Java Performance Tuning

80 - Internal Use Only -

G1 Collector

• 장기적으로 CMS 를 대체하는 low pause time, low latency Collector

• Sun 연구소의 유산

• Java7u4+ 부터 공식 지원

• Java8 Update 로 Deteministic G1 옵션 추가 예정

– Oracle Jrockit Realtime

Page 81: Java Performance Tuning

81 - Internal Use Only -

G1 Collector - Heap

• Heap 을 fixed size 인 “Region” 으로 관리

• 기본 2000개의 Region

• 각각의 Region 은 독립적임

• 개별적으로 GC 가능

• 다른 Region 에서 부터의 모든 Reference 를 Remembered Set 으로 관리

Page 82: Java Performance Tuning

82 - Internal Use Only -

G1 Collector - Generational

• 논리적으로 Young(Eden, Survivor), Old Generation 이 구분 되어 있음

• Young Region 은 고정되어 있지 않고 Region 의 리스트로 이루어져 있음

• 연속된 Region 이 아닐 수도 있음

Page 83: Java Performance Tuning

83 - Internal Use Only -

G1 Collector – Copying, Compacting

• Object 는 Logical Region 으로 Copying

– GC 가 해당 Object 가 속할 Region 을 할당

• Live data Compaction

– CMS 에 가장 큰 문제: Heap Fragmentation

– 지속적인 Compaction 을 통해서 Full GC 경감

Page 84: Java Performance Tuning

84 - Internal Use Only -

G1 Collector – Concurrent Marking

• G1 에서 전체 Heap 을 Scan 하는 경우는 Marking 밖에 없음

• Heap 사용량이 정해진 threshold 를 넘었을 때 (기본 45% 이상)

• Multi Thread 로 수행

Page 85: Java Performance Tuning

85 - Internal Use Only -

G1 Collector – Concurrent Marking

Page 86: Java Performance Tuning

86 - Internal Use Only -

G1 Collector – GC

• Empty Region 은 GC 가 필요 없음

• Full Region 은 너무 많은 Object 를 옮겨야(evacuate) 하므로 GC 대상에서 제외

• 남은 Region 을 두가지 기준으로 분류

– 남은 Object 를 Evacuate 시켜서 얻을 수 있는 메모리의 양

– 해당 Region 에 Object 의 Reference Count, 즉 전체 Reference 를 업데이트 할때의 overhead

Page 87: Java Performance Tuning

87 - Internal Use Only -

G1 Collector – GC 수행

Page 88: Java Performance Tuning

88 - Internal Use Only -

G1 Collector – GC 수행 완료

Page 89: Java Performance Tuning

89 - Internal Use Only -

G1 Collector – GC 수행 완료

Page 90: Java Performance Tuning

90 - Internal Use Only -

G1 Collector – Young & Mixed Collection

• Young Collection

• Eden, Survivors

• 적정한 Age 의 Object Old 영역으로 이동

• Mixed Collection

• Old Collection. Young Collection 도 같이 수행 할 수 있음

• Marking Cycle 이 끝난 이후에야 수행

• Full Collection

• 기본적으로 Full Collection 은 존재하지 않음

• 최악의 경우 Singe Thread Full Compaction

Page 91: Java Performance Tuning

91 - Internal Use Only -

G1 Collector – Basic Command

• -XX:+UseG1GC

• -XX:MaxGCPauseMillis=200

• Target GC PausTime 설정

• 정확히 보장해 주진 않지만 준수하도록 노력

• -XX:InitiatingHeapOccupancyPercent=45

• Concurrent GC 를 수행하는 Heap 사용량

threshold

• Concurrent Marking

Page 92: Java Performance Tuning

92 - Internal Use Only -

G1 Collector – Diagnostics Option

• -XX:+PrintAdaptiveSizePolicy

0.485:[G1Ergonomics (CSet Construction) finish choosing CSet, eden: 2 regions, survivors: 0 regions, old: 0 regions, predicted pause time: 100.82 ms, target pause time: 200.00 ms]

0.490: [G1Ergonomics (Heap Sizing) attempt heap expansion, reason: recent GC overhead higher than threshold after GC, recent GC overhead: 15.60 %, threshold: 10.00 %, uncommitted: 3213885440 bytes, calculated expansion amount: 642777088 bytes (20.00 %)]

Page 93: Java Performance Tuning

93 - Internal Use Only -

G1 Collector – Diagnostics Option

• -XX:+PrintGC == fine

[GC pause (G1 Humongous Allocation) (young) (initial-mark) 24M->21M(64M), 0.2349730 secs]

[GC pause (G1 Evacuation Pause) (mixed) 66M->21M(236M), 0.1625268 secs]

Page 94: Java Performance Tuning

Hotspot GC Tuning 실전

Page 95: Java Performance Tuning

95 - Internal Use Only -

Hotspot Tuning – 기본

• 항상 –Xmx = -Xms

• Heap size 를 늘릴 때 마다 항상 Full GC 발생

• Permsize

• -XX:PermSize = -XX:MaxPermSize

• 역시 Size 가 늘어날때 마다 Full GC 발생

• Java Hotspot 8 부터 Permanent 영역 사라짐

• 전체 JVM Heap 이 가용 메모리의 90% 미만을 유지

• OS 및 기타 프로세스들이 쓸 메모리를 남겨서 Swapping 방지

Page 96: Java Performance Tuning

96 - Internal Use Only -

Hotspot Tuning – Latency (Response Time)

• Target Pause Time 에 대한 기준치가 필요

• Low Latency Collector 를 이용하여 GC 에 대한 통계 자료 추출

• Tenuring Threshold Tuning

• Promotion 을 적절히 조절하여 GC 부하 경감

• 적절한 Heap Sizing

• GC 가 처리할 수 있는 Garbage 의 양 (Throughput)

• 앞에서 도출된 목표 pause time 을 맞출 수 있도록 GC Throughput 에 따라 Heap 의 사이즈를 조정

Page 97: Java Performance Tuning

97 - Internal Use Only -

Hotspot Tuning – Latency (Response Time)

• 가장 이상적인 Case

• Survivor Space 더 작게 조정

Page 98: Java Performance Tuning

98 - Internal Use Only -

Hotspot Tuning – Latency (Response Time)

• Survivor Size 가 너무 작으므로 크게 조정

Page 99: Java Performance Tuning

99 - Internal Use Only -

Hotspot Tuning – Latency (Response Time)

• TenuringThreshold 를 더 늘려보고 여전히 50000bytes 이상이 유지되면 아예 Threshold 를 2~3 정도로 줄인다

Page 100: Java Performance Tuning

100 - Internal Use Only -

Hotspot Tuning – Heap Sizing

• Young Generation

• Size 는 기본 전체 Heap size 의 10% 이상

• Size 에 따른 GC 빈도 / pause time

• Old Generation Size 는 live data 에 최소 1.5배 이상의 사이즈

• Permanent Size 는 live data 에 최소 1.2~ 1.5 배 이상

Page 101: Java Performance Tuning

101 - Internal Use Only -

Hotspot Tuning – Throughput

• 일반적으로 더 많은 메모리를 사용 할 수록 더 나은 Throughput

• Throughput GC 의 경우 Target 은 기본 5% 미만, 최대 1%

Page 102: Java Performance Tuning

102 - Internal Use Only -

Hotspot Tuning – CMS

• Old 영역 사이즈를 최소 20~30% 이상 증가시킬 것

• Promotion 에 민감

• CMS 에서 Promotion 은 부하가 많이 걸리는 작업

• Fragmentation 이 발생

• 결국 Full GC 를 피할 수 없음

• Full GC 를 피할 수 없으므로, Full GC 의 시점을 사용자가 결정하는 것이 좋음(System.gc 혹은 재기동)

• Tuning Target 은 기본 10% 미만, 최대 3% 정도

Page 103: Java Performance Tuning

103 - Internal Use Only -

Hotspot Tuning – CMS Initiating Threshold

• CMS Cycle 을 너무 일찍 수행

• 너무 잦은 GC

• CMS Cycle 을 너무 늦게 수행

• Full GC 유발

• 너무 늦게 하는 것 보다는 일찍 수행 하는 것이 더 나은 선택

• 옵션을 주지 않을 경우 JVM 이 알아서 판단(Heuristics)

Page 104: Java Performance Tuning

104 - Internal Use Only -

Hotspot Tuning – CMS Initiating Threshold

• -XX:CMSInitiatingOccupancyFraction=<percent>

• 주어진 percent 이상 Old 영역이 차면 CMS 수행

• 보통 75를 기준으로 시작해서 낮춘다

• -XX:+UseCMSInitiatingOccupancyOnly 반드시 필요함. 이 옵션이 없으면 JVM 이 Heuristics 알고리즘으로 알아서 CMS 수행 판단

Page 105: Java Performance Tuning

105 - Internal Use Only -

Hotspot Tuning – CMS Promotion Failure

20416.613: [CMS-concurrent-sweep-start]

20420.628: [CMS-concurrent-sweep: 4.004/4.015 secs]

20420.628: [CMS-concurrent-reset-start]

20420.892: [CMS-concurrent-reset: 0.264/0.264 secs]

20422.176: [Full GC 20422.177: [CMS (concurrent mode failure

): 1815018K->912719K(1835008K), 18.2639275 secs] 1442583K->9

12719K(2523136K), [CMS Perm : 202143K->142668K(262144K)], 18

.2649505 secs]

• CMS 가 끝나기전에 Heap 이 다 차버려서 Full GC 발생

• CMS Initiation Occupancy 를 낮게 조정

Page 106: Java Performance Tuning

106 - Internal Use Only -

Hotspot Tuning – CMS Promotion Failure

197.976: [GC 197.976: [ParNew: 260872K->260872K(261952K), 0.000

0688 secs]

197.976: [CMS197.981: [CMS-concurrent-sweep: 0.516/0.531 secs]

(concurrent mode failure): 402978K->248977K(786432K), 2.3728734

secs] 663850K->248977K(1048384K), 2.3733725 secs]

• ParNew 가 실행되었지만 CMS generation 이 꽉 차서 “Full GC” 가 발생

• CMS Initiation Occupancy 를 낮게 조정

Page 107: Java Performance Tuning

107 - Internal Use Only -

Hotspot Tuning – CMS Full GC

429417.135: [GC 429417.135: [ParNew: 1500203K->100069K(1747648K), 0.3973722 secs] 3335352K->1935669K(3844800K), 0.3980262 secs] [Times: user=0.85 sys=0.00, real=0.40 secs] 430832.180: [GC 430832.181: [ParNew: 1498213K->103052K(1747648K), 0.3895718 secs] 3333813K->1939101K(3844800K), 0.3902314 secs] [Times: user=0.83 sys=0.01, real=0.39 secs] 431370.238: [Full GC 431370.238: [CMS: 1836048K->1808511K(2097152K), 43.4328330 secs] 2481043K->1808511K(3844800K), [CMS Perm : 524287K->475625K(524288K)], 43.4336938 secs] [Times: user=40.13 sys=0.73, real=43.43 secs]

• PermGen 이 꽉차서 Full GC 발생

• PermSize 를 늘리거나 –XX:+CMSClassUnloadingEnabled 옵션

Page 108: Java Performance Tuning

108 - Internal Use Only -

Hotspot Tuning – G1 Tuning

• Ergonomics 를 이용한 자동 최적화

• 사용자의 설정을 최대한 단순화 (G1 20+ vs CMS 80+)

• Young Generation Size 주지 말 것

• 최소 Heap 의 20% 최대 80% 까지 JVM 이 dynamic 하게 조정

• -Xmn 으로 disable 은 가능함

• Marking Thread 개수 증가

• -XX:ConcGCThreads=n

• Evacuation Failure 발생시

• -XX:G1ReservePercent 조정. 기본값 10 이상으로.

• -XX:InitiatingHeapOccupancyPercent 조정. 기본값 45 미만으로

Page 109: Java Performance Tuning

109 - Internal Use Only -

Hotspot Tuning – CMS Options

• -XX:+CMSScavengeBeforeRemark

– Remark 전에 minor GC 수행하여 marking 할 대상을 줄임

• -XX:+ParallelRefProcEnabled

– WeakReference, SoftReference 등을 많이 사용시에 Single Thread(default) 가 아닌 Multi Thread 로 finalize 가능한 reference 들 확인

Page 110: Java Performance Tuning

110 - Internal Use Only -

Hotspot Tuning – GC Thread 개수 조정

• 명시적으로 Count 를 주지 않을 경우 default 값

• ParallelGCThreads = (ncpus <= 8) ? ncpus : 3 + ((ncpus * 5) / 8)

• ParallelCMSThreads = (ParallelGCThreads + 3) / 4

• 머신에 core 개수 / JVM 개수 를 기준치로 하여 Thread 개수 할당

Page 111: Java Performance Tuning

Hotspot Tuning 추가

Page 112: Java Performance Tuning

112 - Internal Use Only -

Hotspot Tuning 추가 – Explicit GC

• System.gc()

– Compaction

– -XX:+DisableExplicitGC

– CMS 사용시 예외적으로 사용하는 case

• CMS 사용시는 –XX:+ExplicitGCInvokesConcurrent

• -Dsun.rmi.dgc.client.gcInterval=600000

• -Dsun.rmi.dgc.server.gcInterval=600000

Page 113: Java Performance Tuning

113 - Internal Use Only -

Hotspot Tuning 추가 – Constant pool

• Constant String 은 Permanent 영역에 String Constant pool(literal pool) 이라는 곳에 저장.

– Flyweight pattern

• substring?

Page 114: Java Performance Tuning

114 - Internal Use Only -

Hotspot Tuning 추가 – Constant pool

• -XX:StringTableSize 로 사이즈 조정가능

• Java 6 : 1009

• Java 7+ : 60013

• Performance vs Memory Size

• -XX:+PrintSTringTableStatistics

• String.intern()

Page 115: Java Performance Tuning

115 - Internal Use Only -

Hotspot Tuning – Large Pages

• -XX:+UseLargePages

• Solaris 에서는 default On

• -XX:LargePageSizeInBytes=4m

• OS 나 Chip Maker 에 따라 틀림

• X86 에서는 보통 최대 2M

• 최대 15% 정도의 성능 향상 효과

Page 116: Java Performance Tuning

116 - Internal Use Only -

Hotspot Tuning – Transparent HugePage

• Turn off Transparent Huge Page Optimization

• RedHat 기반 Linux • Centos

• Oracle Linux

• /sys/kernel/mm/transparent_hugepage/enabled

• $ echo “never” > enabled

Page 117: Java Performance Tuning

117 - Internal Use Only -

Hotspot Tuning – OS Level

Platform(OS) Tuning

• TCP 파라미터 튜닝, OS 스레드 파라미터, 파일 디스크립터 튜닝,

예> 리눅스 커널 파라미터 튜닝

파라미터 기본값 변경값 내용

net.ipv4.neigh.default.unres_qlen 3 100 Increase TCP

net.ipv4.tcp_keepalive_time 7200 30 Drop keep-alive time

net.ipv4.tcp_fin_timeout 60 10 Drop it so lack of FIN times out quicker

net.core.netdev_max_backlog 1000 2500 Increase number of incoming connections backlog

net.ipv4.tcp_retries1 3 2 How many times to retry killing an alive TCP connection

net.ipv4.tcp_retries2 15 3 How many times to retry killing an alive TCP connection

net.ipv4.ip_local_port_range 32768 61000 1024 65000 Increase Local port range

net.core.rmem_max 131071 16777216 Max TCP Receive Buffer

net.core.rmem_default 109568 16777216 Default TCP Receive Buffer

net.core.wmem_max 131071 16777216 Max TCP Send Buffer

net.core.wmem_default 109568 16777216 Default TCP Send Buffer

net.ipv4.tcp_window_scaling 0 1 Enable really big(>65kb) TCP window scaling

net.ipv4.tcp_timestamps 1 0 Turn off timestamp

net.ipv4.tcp_sack 1 0 Turn off tcp sack

net.ipv4.tcp_orphan_retries 7 0 유저 파일 핸들에 할당되지 않은 연결에 몇번 재시도 할지

vm.swappiness 10 1 Swap 사용량 결정

Page 118: Java Performance Tuning

Middleware Tuning

Page 119: Java Performance Tuning

119 - Internal Use Only -

Middleware Tuning

Middleware Performance 병목의 단골 손님

• CPU – 스레드 경합에 의한 비정상적인 CPU 사용

• Network – CPU 대기 시간 및 네트워크 부하.

• Disk – 실제 디스크에 대한 물리적인 초당 디스크 입출력(Disk I/O). 일반적

인 경우 모니터링 측정치가 20ms 이상이면 잠재적인 병목으로 진단함.(sar,

iostat) – 특히 logging

• Java Heap – 가비지 컬렉션이 시간이 응답시간의 15%이상을 차지하면 사

이즈 조정 필요

• WAS Thread Pool – 요청 큐로 보면 되며 동시 대기 스레드가 많아질 경우

병목이 발생

• JDBC Connection Pool – 데이터 베이스 풀 개수로 인한 성능 병목 현상

발생

Page 120: Java Performance Tuning

120 - Internal Use Only -

Middleware Tuning

어떻게 문제 구간을 확인할 수 있는가?

• 항상 첫 번째로 각 서버의 CPU를 주시하라!

Web / WAS Server Database Server

Cluster

LoadRunner PC

LoadRunner (PC 10 EA)

Web Server

App Server

App Server

App Server

App Server

Plug-in

JDBC Thin

1000 Virtual User

Web Server App Server DB Server Where tune?

High Low Low

Suitable High Low

Suitable Low High

Suitable High High

Page 121: Java Performance Tuning

121 - Internal Use Only -

Middleware Tuning

깔때기 이론

• 일정한 처리량일 경우 요청 유입이 많아진다면?

• 아래의 그림에서 처리량을 늘려줄 수 있는 방법은?

• 하부에 DB가 있을 경우 WAS vs DB의 CPU는 어떤 상태를 보일까?

요청 유입

요청 큐잉(Request Queue)

처리량(Response)

WAS 구간

Page 122: Java Performance Tuning

122 - Internal Use Only -

Middleware Tuning

성능 장애 요인 파악 – Absolute Performance Problem

• 애플리케이션 처리 미비 - JDBC 리소스 미 반환에 의한 장애

• 명시적 Commit/Rollback 미비로 인한 DB Connection Leak

• 메모리 관련 장애(과다 메모리 사용, 누수(Memory Leak), Native Memory

Leak)

• 시스템 WAS 튜닝 미비에 의한 장애(Pool Size, Thread 개수, Heap Size)

• JVM/WAS/JDBC 등 제품의 버그에 의한 장애(JDBC Driver, JVM Bug,

WAS Bug)

• 라이브러리 등에서의 Thread Lock/Dead Lock에 기인한 장애(예: Log4j

1.2.6)

• 대용량 파일/SOAP 메시지 처리

• 비규칙적 애플리케이션 무한루프/CPU 100%

Page 123: Java Performance Tuning

123 - Internal Use Only -

Middleware Tuning

성능 장애 요인 파악 – Relative Performance Problem

• 하드웨어 용량 부족 (메모리, CPU 등)으로 인한 성능 저하 및 장애.

• 네트워크 용량 문제

• 연계 시스템일 경우 대상 시스템의 응답 속도 저하로 인한 병목

• Back-end 트랜잭션의 상대적 성능 저하 (TP-모니터 : Tuxedo, CICS, Tmax)

• EAI Adapter 처리 방식으로 인한 성능 저하(XML Parsing 등)

• SQL Query 성능 저하로 인한 장애(대용량 쿼리, Full scan 등)

Page 124: Java Performance Tuning

124 - Internal Use Only -

Middleware Tuning

병목 해결을 위한 구조

• 근본적인 문제를 찾아야 한다.

• 잘못된 접근법

• WAS의 Thread 수 증가시킴

• JDBC Connection Pool 증가시킴

• 유입되는 모든 요청을 처리할 수 있는 모델

웹 서버

플러그인

WAS

DB

Request

Page 125: Java Performance Tuning

125 - Internal Use Only -

Middleware Tuning

애플리케이션 구간 처리 시간 분석 병행

• 애플리케이션 로그를 통한 각 구간별 로그를 저장 후 문제 지점 분석

1. 요청과 동시에 UUID와 같은 식별키를 이용하여 트랜잭션 ID 채번 후 시간 로그를 남김

2. 대상 시스템 호출 직전 요청 시간을 남김

3. 대상 시스템으로부터 응답과 동시에 현재 시간에 대한 로그를 남김

4. 호출 측으로 응답을 반환하기 직전 트랜잭션 아이디와 함께 로그를 남김

• 대상 시스템 응답 시간을 얼마인가?

• 시스템 내에서 처리한 순수한 시간은 얼마인가?

Adapter

Adapter

Adapter

Adapter Source Target

① ②

③ ④

Page 126: Java Performance Tuning

126 - Internal Use Only -

Middleware Tuning

사용자 및 TPS의 상관 관계

Saturation point

Res

pons

e Tim

e

User Load

X

100users User Load

Thr

oug

hput

X Saturation point

Util

izat

ion

User Load

X Saturation point

Page 127: Java Performance Tuning

127 - Internal Use Only -

Middleware Tuning

가장 이상적인 모습

Page 128: Java Performance Tuning

128 - Internal Use Only -

Middleware Tuning

증상 1 • 다음의 그래프를 보았을 때 예상할 수 있는 문제점은?

Page 129: Java Performance Tuning

129 - Internal Use Only -

Middleware Tuning

예상 1 • 증상

응답 속도(Response Time)가 수행 도중 급격하게 떨어짐.

TPS가 가끔씩 비정상적으로 증가

• 예상

CPU 경합(lock contention)

• 왜 발생하는가?

특정 jar 파일을 여러 개의 스레드가 액세스

Synchronized 블록에 대한 멀티 스레드 처리

• Thread dump 시 보통 ‘waiting to lock’ 형태로 발견됨.

• 해결

덤프 등을 통하여 문제 발생 라이브러리 혹은 코드를 통해서 해결.

Page 130: Java Performance Tuning

130 - Internal Use Only -

Middleware Tuning

증상 2

Page 131: Java Performance Tuning

131 - Internal Use Only -

Middleware Tuning

예상 2 • 증상

사용자와 함께 TPS 증가 후 특정 시점 급격히 감소

• 예상

Gabage Collection 문제는 아닌 것으로 예상됨.

리소스에 대한 문제로 의심.

• 왜 발생하는가?

너무 많은 스레드로 인한 과도한 컨텍스트 스위칭

코드 내 스레드의 sleep으로 인한 상태 변화

OS 관련 파라미터(멀티 스레드 관련)의 잘못된 설정

• 실제로 대량 스레드에 대한 context switch가 많이 발생하여 나타난 결과

Page 132: Java Performance Tuning

132 - Internal Use Only -

Middleware Tuning

증상 3

Page 133: Java Performance Tuning

133 - Internal Use Only -

Middleware Tuning

예상 3 • 증상

20 user 시점까지 정상증가 후 이후 서서히 감소

• 예상

CPU 경합 현상 패턴은 아님.

메모리 누수일 경우 이와 같은 그래프가 자주 보임

• 왜 발생하는가?

Static Collection 객체 등에 지속적인 데이터 삽입

• 확인 방법

시스템 자원 모니터링을 통하여 문제점 파악

Page 134: Java Performance Tuning

134 - Internal Use Only -

Middleware Tuning

증상 4

Page 135: Java Performance Tuning

135 - Internal Use Only -

Middleware Tuning

예상 4 • 증상

초기 TPS는 크게 증가하나 바로 떨어진 후 안정화

CPU, 메모리 사용량 거의 없음

• 예상

Leak, CPU 경합은 없을 것으로 예상됨(단지 예상임)

적정 스레드 개수를 잘못 산정

• 왜 발생하는가?

과도한 웹 서버의 스레드, WAS 스레드

• 실제 Apache worker 스레드를 과도하게 설정하여 나타난 문제

변경후

Page 136: Java Performance Tuning

136 - Internal Use Only -

Middleware Tuning

증상 5

Page 137: Java Performance Tuning

137 - Internal Use Only -

Middleware Tuning

예상 5 • 증상

부하 시 지속적으로 응답 시간 증가 후 응답 없음

• 예상

Long-running 트랜잭션들이 많은 확률

대용량 쿼리를 사용하는 애플리케이션이 있을 가능성

• 대용량 쿼리 실행 시 파급 효과

Heap 메모리 지속적 증가

응답 지연으로 인한 요청 큐(request queue)에 누적

수행중인 다른 트랜잭션들의 time-out 발생

메모리 확보를 위한 JVM의 과도한 GC 작업 발생

결국 서버가 다운되는 현상(복구되는 경우 거의 없음)

Page 138: Java Performance Tuning

138 - Internal Use Only -

Middleware Tuning

요약

• 문제가 발생하는 곳에서 모든 추론을 동원할 것.

• 호기심이 문제 해결을 이끈다.

문제의 실체에 접근할 수 있는 모든 경로를 탐색하라.

모든 사건에 대해 “왜(why)?”를 붙이도록 한다.

• 모든 시스템 리소스에 대한 지속적인 모니터링이 필요

• 모든 작업은 기록을 통해 하나씩 순차적으로 해결해야 한다.

한꺼번에 두 가지 파라미터 등을 변경하고 테스트 하는 것은 없다.

한번에 하나씩 테스트하고 모든 항목을 기록한다.

Page 139: Java Performance Tuning

139 - Internal Use Only -

Middleware Tuning – Tuning Point

WAS 튜닝 포인트 • 각 영역별 JMX를 통한 모니터링 방법을 가지고 있어야 함.

• WAS 구동을 위한 GC 옵션

• 문제 발생시 Thread Dump를 통한 문제 분석

Web Application Server

DBMS EJB

EJB

DB Connection Pool

Thread Pool

Request

EJB Pool

JDBC

Request Queue

Execute Thread Execute Thread Execute Thread

Pooling

Pooling

Pooling

Page 140: Java Performance Tuning

140 - Internal Use Only -

Middleware Tuning – Tuning Point

주요 튜닝 포인트

• Native IO – Performance Pack

• Execute Thread

• Request Queue Size

• Socket Reader

• 너무 많은 실행 스레드 설정을 오히려 성능을 저하시킬 수 있음.

• 새로운 스레드를 지속적으로 생성하는 애플리케이션 디자인은

피해야 함.

Page 141: Java Performance Tuning

141 - Internal Use Only -

Middleware Tuning – Tuning Point

JDBC Connection Pool

• 커넥션 풀 사이즈 및 테스트 옵션

• Statement 캐시

• 컨넥션 풀 요청 타임아웃

• 반환되지 않은 커넥션 자동 closing 옵션 활성화

• 일반적으로 초기 연결값과 최대 연결값을 같도록 설정

데이터 베이스 등의 소켓 연결작업은 상당한 리소스를

필요로 함.

• 최대 커넥션 개수는 WAS의 최대 실행 스레드(execute

thread)를 넘지 않도록 함

Page 142: Java Performance Tuning

142 - Internal Use Only -

Middleware Tuning – Tuning Point

EJB Tuning

• EJB Pool 개수 튜닝

• CMP 튜닝

Relationship-caching, Entity 빈에 연관된 Pre-

fetching

• JNDI Lookup 캐시를 통한 EJB 레퍼런스

• 동일한 JVM일 경우 Local Interface를 사용

• 애플리케이션 범위의 캐시를 사용

Page 143: Java Performance Tuning

143 - Internal Use Only -

Middleware Tuning – Tuning Point

JMS Tuning • JMS Persistence Store 의 적절한 선택

File, Memory, JDBC

• 메시지 플로우 컨트롤을 통한 조절

• 만료된 메시지(Expired Message) 제어

• 메시지 유형(Byte, Object, XML 등) 및 전달(Queue, Topic) 방식 선택

?

Sender Receiver Connection

Session

Producer

Consumer

Remoting Core

Client-side Delegates

Client-side aspects

Server-

side

aspects

Server-side

endpoints

Page 144: Java Performance Tuning

144 - Internal Use Only -

Middleware Tuning – Tuning Point

Servlet/JSP Tuning • 세션 관리(Session Management)

• 세션 저장 전략

Memory

File System

Database

• 세션 속성 설정

세션 타임 아웃 시간

세션 캐시 사이즈

• JSP 사전 컴파일(pre-compile) 기능 사용

• 서블릿 재로딩 기능

• 요청마다 페이지 변경 확인 기능 제거

• <% page session=“false”%>를 통해 세션 자동 생성 기능 억제

Page 145: Java Performance Tuning

Trouble Shooting 개요

Page 146: Java Performance Tuning

146 - Internal Use Only -

목차

문제해결 과정

시스템 모니터링 도구

JVM 모니터링 도구

Error와 Exception에 대하여

Page 147: Java Performance Tuning

147 - Internal Use Only -

Trouble Shooting 개요

문제 해결 과정

오류발생

조치 (상황 수집, 로그설정)

진단 & 모니터링

자료수집 & 재현

원인분석

원인제거 (Work Around)

Page 148: Java Performance Tuning

148 - Internal Use Only -

Trouble Shooting 개요

수집 자료는? • 기본 수집 자료

로그!

Thread dump!

기본 환경 설정 정보

• 관련된 상황은?

언제

어떤 서버, 어느 인스턴스에서 정확한 OS, JVM, WAS 버전은?

발생 주기는?

재현은 되는지?

• 어떤 영향을 미치는지?

Business 부서의 영향은?

• 관련된 네트웍, H/W 및 S/W는 어떤 것인지?

대상 시스템에 로그나 상황은 어떤지 체크

Page 149: Java Performance Tuning

149 - Internal Use Only -

Trouble Shooting 개요

• java.lang.Throwable을 상속한 Java Object는 Exception과 Error가 있다

• Error는 중대한 에러가 발생할 때 JVM에서 발생

NoClassDefFoundError, OutOfMemoryError, StackOverflowError

• Exception을 다시 Throw 할때는

catch(Exception e){ throw e; }

• Exception을 stdout에 출력하려면

e.printStackTrace()

• Exception을 던질때 stack 정보를 넣으려면

throw e.fillInStackTrace();

• Thread.currentThread().dumpStack();

코드를 삽입하여 현재 코드가 어디서부터 호출되었는지 체크

복잡한 시스템에서 문제가 발생하는 부분부터 시작하는 호출관계를 파악할 수 있기 때문

에 유용한 디버깅 방법

Exception과 Error는 다르다

Throwable

Exception Error

RuntimeException

Sub classes…

Other Exception... Unchecked

Checked

구분 Checked Unchecked

처리 프로그램에서 JVM에서

try catch 반드시 사용가능

체크시간 컴파일시, JVM 체크 Runtime시

발생하는 경우 원할때 버그 발생시

Page 150: Java Performance Tuning

150 - Internal Use Only -

Trouble Shooting 개요

문제해결을 위해서 • 로그 등 관련 자료는 충분히 확보해야

로그는 첫 번째 문제부터 살펴봐야

• 섣부른 추측은 금물

전해들은 말을 100% 믿지 말라

증거에 의존하여 분석

문서를 100% 믿지 말라

• 문제분석

문제를 분리하는 방법(Divide & Conquor)

코드 샘플링을 통한 분리

테스트 & 테스트

Page 151: Java Performance Tuning

Server Hang & Slowdown 문제

Page 152: Java Performance Tuning

152 - Internal Use Only -

목차

Server Hang & Slowdown

Process 와 Thread

Server Hang 의 원인

Thread Dump 란

높은 CPU 사용률 문제

높은 CPU 사용률 문제 분석 방법

Page 153: Java Performance Tuning

153 - Internal Use Only -

Server Hang & Slowdown

Server Hang 이란? • 서버가 전혀 Response를 주지 못함 서버 Hang

• 느리더라도 Response를 준다 서버 Slowdown

• 서버 Hang의 증상

Request가 처리되지 않는다

새로운 Request를 받지 못하고 기존 Request가 Timeout되거나 응답이 없는 상황

서버가 아무 작업도 하지 않는 것 같다

서버의 증상:

Hang이 오래 지속되면 JVM Crash될 수도 있다(항상은 아님)

그냥 두면 Hang이 풀리는 경우도 있다

(리소스 경합이 발생하여 Hang이 발생한 경우에는 Resource가 풀리면 Hang이 풀린

다)

대부분 Hang이 발생된 후에는 관리자의 조치가 없으면 Hang 상태로 무한이 남아있게

된다

Page 154: Java Performance Tuning

154 - Internal Use Only -

Server Hang & Slowdown

Process 와 Thread • 프로세스:

운영체제에서 process ID(PID)로 인식됨 단일 스레드나 멀티 스레드로 동작

• 스레드: 프로세스의 sub-task 다른 Thread와 독립적으로 CPU등의 리소스를 사용 어떤 OS에서는 PID에 매핑되기도 함(구 버전 Linux의 green thread) 부모 프로세스의 LWPID(Light Weight Process ID)로 구분되기도 함

Page 155: Java Performance Tuning

155 - Internal Use Only -

Server Hang & Slowdown

ThreadPooling

WLS JBoss

Page 156: Java Performance Tuning

156 - Internal Use Only -

Server Hang & Slowdown

ServerHang의 주요 원인 • 리소스 부족

스레드나 메모리 부족 CPU 과점유나 OutOfMemory 에러발생

파일 핸들이 부족한 경우 Too many Open Files 에러가 발생

리소스 경합이나 Dead Lock이 발생하는 경우

JDBC Dead Lock이 발생하는 경우

JNDI Lookup에서 경합이 발생하는 경우

Application Dead Lock

JSP 컴파일 주기가 짧아서 발생하는 Hang

• Hang 처럼 보이는 경우

리소스 경합의 경우 리소스가 가용해지면 조금씩 풀리는 경우

Full GC 시간이 오래 걸리는 경우

JVM에서 Code Optimization시 Hang이 걸리는 경우

Page 157: Java Performance Tuning

157 - Internal Use Only -

Server Hang & Slowdown

Thread Dump 의 정의

"ajp-/192.168.0.172:8109-Poller" daemon prio=10 tid=0x00007f582407b000 nid=0x2d3c in Object.wait() [0x00007f5861219000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000fe31e848> (a org.apache.tomcat.util.net.JIoEndpoint$Poller) at org.apache.tomcat.util.net.JIoEndpoint$Poller.run(JIoEndpoint.java:732) - locked <0x00000000fe31e848> (a org.apache.tomcat.util.net.JIoEndpoint$Poller) at java.lang.Thread.run(Thread.java:722)

Java Thread Dump는 Java Process에서 수행되는 thread들이 무엇을 하고 있는지 snapshot을 텍스트 형태로 화면에 출력해 준다.

서버 Hang, 서버 Slowdown등 서버에서 발생하는 문제를 해결하는 가장 유용한 도구 약 3~5초간격으로 3~5회 연속해서 스레드 덤프를 받아야 분석이 가능하다

언제 받아야 하나?

서버 Hang, Slowdown시, 서버가 Crash되거나 OutOfMemory 발생 직후에 받는 것이 좋음

Thread 정보

Thread Stack 정보

Page 158: Java Performance Tuning

158 - Internal Use Only -

Server Hang & Slowdown

Thread Dump 추출 방법은? Java Thread Dump를 추출하기 위해서는 Java Process에 SIGQUIT signal을 보내면 추출된다.

타입 Thread Dump 추출 방법

Unix 계열 Foreground 일 경우 : CTRL+\

Background 일 경우 : kill 명령어로 SIGQUIT 보냄; kill –SIGQUIT PID | kill –QUIT PID | kill –3 PID

MS 계열

Foreground 일 경우 : CTRL+BREAK

Window Service로 수행된 경우 : SendSignal pid

SendSignal은 별도 유틸리티 : http://www.latenighthacking.com/projects/2003/sendSignal/SendSignal.exe

Java Process - PID 12

VM Thread

Signal Dispatcher

Finalizer

Low Memory Detector

GC Thread #n

User Thread #n

Terminal

kill –SIGQUIT 12 or kill –QUIT 12 or kill -3 12 or jstack 12

Signal Dispatcher

Page 159: Java Performance Tuning

159 - Internal Use Only -

Server Hang & Slowdown

•Signal은 유닉스 시스템에서 프로세스간 통신에 많이 사용되었던 전통적인 방법 중의 하나로 프로세스들 간 혹은 커널과 프로세스 간의 비동기적으로 이벤트를 알리기 위해서 사용 이 됨.

•유닉스 signal은 유닉스 계열마다 조금씩 차이가 있으나 기본적으로는 POSIX의 표준을 준수함.

•Java Virtual Machine도 해당 Unix 기반 하에 올라가는 응용 프로그램으로 Signal에 따라서 동작하는데 대표적인 예를 들어 보면 다음과 같음.

– 사용자가 임의로 Thread Dump를 추출하기 위해서 JVM 프로세스에 Signal를 보내는 경우

– JVM이 자기 소유가 아닌 Memory Access를 하여 Kernal이 Signal를 보내 Core Dump 발생

Signal 이란?

User Process User Process …

Kernel

Signals Signals

Signals

Page 160: Java Performance Tuning

160 - Internal Use Only -

Server Hang & Slowdown

Signal 보내는 방법은?

•Signal를 해당 프로세스에 보내는 방법은 다음과 같다.

– Keyboard로 보내는 방법 : ex> Ctrl-C, Ctrl-Z, Ctrl-\ – Command Line에서 보내는 방법 : ex> kill -<signal> <PID> – Kernel이 보내는 방법

이름 번호 반응 의미

SIGHUP 1 Exit Hangup (연결해제)

SIGINT 2 Exit Interrupt ( CTRL-C )

SIGQUIT 3 Core Quit (CTRL-\ )

SIGILL 4 Core Illegal Instruction

SIGTRAP 5 Core Trace/Breakpoint Trap

SIGABRT 6 Core Abort ( abort(3C) )

SIGEMT 7 Core Emulation Trap

SIGFPE 8 Core Arithmetic Exception ( 예: 숫자/0 )

SIGKILL 9 Exit Killed

SIGBUS 10 Core Bus Error (alignment error 등)

SIGSEGV 11 Core Segmentation Fault(virtual memory error 등)

SIGSYS 12 Core Bad System Call

SIGPIPE 13 Exit Broken Pipe

SIGALRM 14 Exit Alarm Clock ( alarm(2) )

이름 번호 반응 의미

SIGTERM 15 Exit Terminated (shutdown)

SIGUSR1 16 Exit User Signal 1

SIGUSR2 17 Exit User Signal 2

SIGCHLD 18 Ignore Child Status Changed

SIGPWR 19 Ignore Power Fail/Restart

SIGWINCH 20 Ignore Window Size Change

SIGURG 21 Ignore Urgent Socket Condition

SIGPOLL 22 Exit Pollable Device Event ( poll(2) )

SIGSTOP 23 Stop Stopped (signal )

SIGTSTP 24 Stop Stopped ( CTRL-Z)

SIGCONT 25 Ignore Continued

SIGTTIN 26 Stop Stopped (backgroud tty input)

SIGTTOU 27 Stop Stopped (backgroud tty output)

SIGVTALRM 28 Exit Virtual Timer Expired

Page 161: Java Performance Tuning

161 - Internal Use Only -

Server Hang & Slowdown

Thread dump 분석의 기본

• 모든 스레드가 사용 중인가?

• 어떤 작업이 일어나고 있는가?

– DB 작업, EJB Call 등등

• Dead Lock은 발생하지 않았나?

– Java Level Dead Lock은 JVM에서 Detect하여 스레드 덤프내에

출력

• 연속된 스레드 덤프를 보며 각 스레드가 움직이고 있는지 확인

– 3-5초 간격으로 3-5회 스레드 덤프를 받는 이유

Page 162: Java Performance Tuning

162 - Internal Use Only -

Server Hang & Slowdown

Thread 동작 상태에 따른 분석

상태 설명

NEW Thread가 생성되기 위해 메모리가 할당된 상태

RUNNABLE Thread가 JVM에 의해 수행되고 있는 상태

BLOCKED Thread가 Monitor Lock을 획득하기 위한 대기 상태

WAITING Thread가 특정 작업을 위해서 다른 Thread를 대기 하는 상태

TIMED_WAITING Thread가 특정 작업을 위해서 정해진 시간 만큼 다른 Thread를 대기 하는 상태태

TERMINATED Thread가 Expired 된 상태

• thread dump상 RUNNABLE 상태에 해당하는 thread 가 지속적으로 보이는가?

• 연계된 Thread에서 BLOCKED 및 wait to lock 이 발생하고 있는가?

"ajp-10.8.12.24-9218-75" daemon prio=10 tid=0x00002b70182f1800 nid=0x7c0e runnable [0x00002b6d3f1c9000] java.lang.Thread.State: RUNNABLE at com.mysql.jdbc.MysqlIO.unpackField(MysqlIO.java:765) …중략 at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2802) - locked <0x0000000717b8e730> (a com.mysql.jdbc.LoadBalancingConnectionProxy)

Page 163: Java Performance Tuning

163 - Internal Use Only -

Server Hang & Slowdown

Thread dump 의 예 (Weblogic) "ExecuteThread: '2' for queue: 'weblogic.socket.Muxer'" daemon prio=10 tid=009404b8 nid=122 lwp_id=3686306 waiting for monitor entry [0x2158d000..0x2158d4f0] at weblogic.utils.http.BytesToString.newString(BytesToString.java:21) at weblogic.servlet.internal.RequestParser.parse(RequestParser.java:195) at weblogic.servlet.internal.MuxableSocketHTTP.dispatch(MuxableSocketHTTP.java:406) at weblogic.socket.MuxableSocketDiscriminator.dispatch(MuxableSocketDiscriminator.java:284) at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:682) at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:628) at weblogic.socket.PosixSocketMuxer.processSockets(PosixSocketMuxer.java:123) at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:32) at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:219) at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:178) ...... "ExecuteThread: '93' for queue: 'weblogic.kernel.Default'" daemon prio=10 tid=0009f8d8 nid=106 lwp_id=3686279 waiting for monitor entry [0x21d9e000..0x21d9d4f0] at java.math.BigDecimal.movePointRight(BigDecimal.java:773) at oracle.sql.NUMBER.toBigDecimal(NUMBER.java:722) at oracle.jdbc.dbaccess.DBConversion.NumberBytesToBigDecimal(DBConversion.java:2805) at oracle.jdbc.driver.OracleStatement.getBigDecimalValue(OracleStatement.java:4728) at oracle.jdbc.driver.OracleStatement.getObjectValue(OracleStatement.java:5907) at oracle.jdbc.driver.OracleStatement.getObjectValue(OracleStatement.java:5833) at oracle.jdbc.driver.OracleResultSetImpl.getObject(OracleResultSetImpl.java:765) - locked <6c326c80> (a oracle.jdbc.driver.OracleResultSetImpl) at oracle.jdbc.driver.OracleResultSet.getObject(OracleResultSet.java:1470) at weblogic.jdbc.wrapper.ResultSet_oracle_jdbc_driver_OracleResultSetImpl.getObject(Unknown Source) at easyi.ezj00.dao.EZJ00A_090DAO.retriBizTrip(EZJ00A_090DAO.java:16066)

Page 164: Java Performance Tuning

164 - Internal Use Only -

Server Hang & Slowdown

Thread dump 분석을 위한 도구 TDA – Thread Dump Analyzer

https://java.net/projects/tda

Page 165: Java Performance Tuning

165 - Internal Use Only -

Server Hang & Slowdown

Thread dump 분석을 위한 도구 samurai

http://yusuke.homeip.net/samurai/en/index.html

Page 166: Java Performance Tuning

166 - Internal Use Only -

Server Hang & Slowdown

Page 167: Java Performance Tuning

167 - Internal Use Only -

Server Hang & Slowdown

High CPU

• 보통 하나의 프로세스나 스레드가 CPU를 많이 점유하여 발생함

Page 168: Java Performance Tuning

168 - Internal Use Only -

Server Hang & Slowdown

High CPU

• 일반적 원인

– WAS 자체의 문제

– 사용자 스레드, 잘못된 코딩, 사용한 라이브러리의 문제 등 다양함

• 증상

– 시스템 CPU를 대부분 사용

– 사용자 Request가 매우 늦거나 Timeout이 많이 발생

– 시스템 자체가 매우 느려짐

• 진단 방법

– 주기적으로 체크해야 함

– OS에서 제공하는 유틸리티를 이용하여 CPU 점유율 분석

– OS마다 분석방법이 다름

Page 169: Java Performance Tuning

169 - Internal Use Only -

Server Hang & Slowdown

Linux 시스템에서 분석방법

• 예전엔 스레드가 프로세스에 매핑되어 사용

• 현재는 POSIX native 스레드를 사용하면서 한 프로세스 사용

• 분석 준비

– top –H 명령으로 어떤 스레드가 CPU를 많이 사용하는지 체크

– kill -3 <PID>로 스레드 덤프를 받음

• 분석

– top –H의 PID는 실제 Thread ID임

– top의 Thread ID를 16진수로 변환

– 스레드 덤프에서 CPU를 많이 사용하는 Thread ID를 찾음

Page 170: Java Performance Tuning

170 - Internal Use Only -

Server Hang & Slowdown

Linux top -H과 스레드 덤프를 이용한 분석

[jboss@KVM2 /opt/was/servers/standalone_ha_11/bin]$ ps -ef|grep java

jboss 11487 11360 0 Nov18 ? 00:04:05 java -D[Standalone] -XX:+UseCompressedOops -server -Xms1024m -Xmx1024m -XX:MaxPermSize=256m -Xloggc:log/gc_20131118184328.log

• Process id 확인

• top 을 이용한 thread 별 CPU 사용량 확인

• 계산기 프로그래머용으로 변경 > Dec > Hex > thread dump의 nid 확인

[jboss@KVM2 /opt/was/servers/standalone_ha_11/bin]$ top -H -p 11487

Swap: 16777208k total, 2625912k used, 14151296k free, 833800k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

11488 jboss 20 0 3547m 512m 4888 S 0.0 6.6 0:00.49 java

11489 jboss 20 0 3547m 512m 4888 S 0.0 6.6 0:00.27 java

11586 jboss 20 0 3547m 512m 4888 S 20.0 6.6 0:00.28 java

"DeploymentScanner-threads - 2" prio=10 tid=0x00007f5824080000 nid=0x2d42 waiting on condition [0x00007f5860bd7000]

java.lang.Thread.State: WAITING (parking)

Page 171: Java Performance Tuning

171 - Internal Use Only -

Server Hang & Slowdown

Solaris 시스템에서 분석방법

• 분석 준비

– prstat -L -p <PID> 1 1 로 CPU 사용률 출력

– pstack <PID>로 LWPID 얻음

– kill -3 <PID>로 스레드 덤프를 받음

• 분석

– prstat에서 CPU 많이 사용하는 스레드 찾기

– pstack에서 LWPID 에 대한 스레드 번호 얻음

– 스레드 번호를 16진수로 변환

– 스레드 덤프에서 CPU를 많이 사용하는 Thread ID를 찾음

Page 172: Java Performance Tuning

172 - Internal Use Only -

Server Hang & Slowdown

Solaris 시스템에서 분석방법 $ prstat -L -p 9499 1 1 PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/LWPID 9499 usera 153M 100M sleep 58 0 0:00.22 0.6% java/8 9499 usera 153M 100M sleep 58 0 0:00.10 0.2% java/10 9499 usera 153M 100M sleep 58 0 0:00.11 0.1% java/9 9499 usera 153M 100M sleep 58 0 0:00.03 0.0% java/5 9499 usera 153M 100M sleep 58 0 0:01.01 0.0% java/1

$ pstack 9499 ----------------- lwp# 8 / thread# 76 -------------------- ff29d190 poll (e2e81548, 0, bb8) ff24d154 select (0, 0, 0, e2e81548, ff2bf1b4, e2e81548) + 348 ff36b134 select (0, bb8, 7fffffff, fe4c8000, 0, bb8) + 34 fe0f62e4 __1cCosFsleep6FpnGThread_xl_i_ (0, bb8, fe4c8000, 1, 0, 1e2fd8) + 234 fe23f050 JVM_Sleep (2, 0, bb8, fe4de978, fe4c8000, 1e2fd8)

$ kill -3 p 9499 "Thread-6" prio=5 tid=0x1e2fd8 nid=0x4c waiting on monitor [0xe2e81000..0xe2e819d8] at java.lang.Thread.sleep(Native Method)

Page 173: Java Performance Tuning

173 - Internal Use Only -

Server Hang & Slowdown

스크립트를 이용한 prstat/pstack과 스레드 덤프 출력

for loopnum in 1 2 3 do prstat -L -p $1 1 1 >> dump_high_cpu.txt pstack $1 >> dump_high_cpu.txt kill -3 $1 echo "prstat, pstack, and thread dump done. #" $loopnum sleep 2 echo "Done sleeping." done

• 거의 동일한 시점의 top과 스레드 덤프를 가지고 분석해야 정확한 결

과를 얻을 수 있음

• 아래와 같은 스크립트를 이용하여 얻은 결과물을 가지고 분석

Page 174: Java Performance Tuning

OutOfMemory 문제

Page 175: Java Performance Tuning

175 - Internal Use Only -

목차

OOM의 유형

Java 메모리 구조

Java Heap

Native Memory

진단방법

Heap Dump분석 도구

Page 176: Java Performance Tuning

176 - Internal Use Only -

OutOfMemory 문제

OutOfMemory의 유형

• Heap의 메모리 OutOfMemory 에러

특정 시각에 급격한 메모리 증가

점차적인 메모리 증가

메모리가 부족한 경우

• Native 메모리의 OutOfMemory 에러

RES 등 OS에서 사용하는 영역에서 발생하는 메모리 부족현상

급격한 증가

점차적인 메모리 증가

• Memory Leak

점차적으로 메모리가 증가하는 현상

메모리를 free하지 못하는 경우에 발생

Page 177: Java Performance Tuning

177 - Internal Use Only -

OutOfMemory 문제

Java 메모리 구조

• Heap은 JVM과 사용자 Java 애플리케이션이 사용하는 메모리 공간

• Java객체는 Eden Survivor Old로 이동

• Heap 이외에 OS에서 사용하는 메모리가 있음

Page 178: Java Performance Tuning

178 - Internal Use Only -

OutOfMemory 문제

OutOfMemory에러 유형

• Old 영역 부족

사용이 끝난 객체의 참조를 끊지 않아 발생 궁극적으로는 Old 영역 부족 현상

가장 일반적인 유형

MAT 등을 이용해서 Memory 할당 주체 파악하여 조치

• Permanent 영역 부족

Permanent 영역은 Java 클래스들이 로딩되는 영역

애플리케이션 사이즈가 매우 커서 실제 Permanent 메모리가 부족해 발생하는

경우가 대부분

JVM 옵션으로 Perm 영역을 늘려준다

개발 머신에서 hot-deploy를 자주할 경우도 많이 발생

Page 179: Java Performance Tuning

179 - Internal Use Only -

OutOfMemory 문제

OutOfMemory에러 유형

• Stack 영역 부족

Java에서 메소드를 호출할 때 내부적으로 Stack 메모리 영역을 사용한다

호출한 곳으로 다시 돌아오기 위해 메모리 주소를 Stack에 보관

재귀호출이 많은 경우엔 Stack영역이 부족하여 오류가 발생하는 경우가 있음

오류 유형

java.lang.OutOfMemoryError:

stack overflow

오류시 StackTrace 정보가 출력되지 않기 때문에 디버깅이 어려움

진단방법 및 해결

일단, –Xss 옵션으로 Stack 영역 메모리를 늘려준다.

스레드 덤프, CPU 사용률 등으로 분석

• 실제 OS 메모리가 부족한 경우

Page 180: Java Performance Tuning

180 - Internal Use Only -

OutOfMemory 문제

Native 메모리는?

• JVM 자체가 쓰는 메모리

• JVM를 구동하기 위해 OS에서 사용하는 메모리

• Native 라이브러리를 사용하는 경우에 이것을 사용하는 메모리

웹로직의 경우 Performance Pack이 이에 해당함

• 일반적으로 Heap을 1G 설정할 경우 OS에서는 1.5G~2G 정도의 메모

리를 점유함

Page 181: Java Performance Tuning

181 - Internal Use Only -

OutOfMemory 문제

Java Heap의 OOM 원인 및 대처방법

• 실제 사용자가 많아서 Java Heap이 부족한 경우

Heap을 늘려준다

WAS 인스턴스 개수를 늘려준다

• HttpSession과 같이 오래 남아있는 객체가 많아서 발생

Session Timeout이 적절한지 체크한다

• 애플리케이션 캐쉬를 너무 많이 사용하여 메모리가 부족한 경우

캐쉬 사이즈를 조정한다

JBoss infinispan같은 분산 캐쉬 라이브러리를 활용하는 것도 방법

• 메모리 Leak

JDBC resultset을 close안한 경우 프로그램을 찾아서 수정해야 함.

• 애플리케이션에서 Singleton 패턴을 잘못 사용한 경우

static Singleton객체에 계속 객체를 추가하는 경우 App 수정해야 함.

• 대용량 쿼리를 사용하는 경우

제한없이 DB에서 메모리로 데이터를 가져오는 경우 App 수정해야 함.

Page 182: Java Performance Tuning

182 - Internal Use Only -

OutOfMemory 문제

Native 메모리 OOM의 원인 및 대처 방법

• 프로세스의 메모리(RAM+Swap)가 OS 한계를 넘어서거나 메모리가 부족한 경우

JVM Heap을 줄인다

시스템 메모리를 증설한다

• JVM Heap이 너무 크게 잡은 경우

OS에 따라서 지정할 수 있는 Heap 사이즈의 한계가 있음

일반적인 32 Bit OS 4G까지 Address를 지정가능하며, Heap은 최대 2G

가 넘을 수 없음(64 Bit OS는 한계가 없음)

• Native 라이브러리나 JNI 코드에서 메모리 Leak

OS에서 JVM의 Core를 받아 메모리를 분석

• -verbose:jni 옵션 설정

Page 183: Java Performance Tuning

183 - Internal Use Only -

OutOfMemory 문제

OOM과 Memory Leak 분석

0. 먼저 verbose:gc 옵션을 설정한다

1. Leak인지 체크

GC 로그를 그래프로 그려서 메모리가 조금씩 증가하는 Leak인지

체크한다

Leak이면 HeapDump를 받아서 분석한다

2. OOM 체크

순간적인 OOM이면 OOM당시의 CPU등 여러가지 자원을 모니터

링하여 분석한다

Page 184: Java Performance Tuning

184 - Internal Use Only -

OutOfMemory 문제

진단 방법

• 진단 도구

JVM의 -verbose:gc 옵션

그래프로 볼 수 있는 도구

VisualVM (http://visualvm.java.net/)

HP JMeter

Samurai의 메모리 Tab (http://yusuke.homeip.net/samurai/en/index.html)

SUN GCPortal

(http://www.oracle.com/technetwork/articles/javase/gcportal-136937.html)

HeapDump 분석도구

IBM AIX HeapAnalyzer

MemoryAnalyzerTool –MAT (http://www.eclipse.org/mat/)

SUN HAT (https://hat.dev.java.net/)

Page 185: Java Performance Tuning

185 - Internal Use Only -

OutOfMemory 문제

GC 모니터링 툴을 이용한 그래프 보기

• HP Jmeter를 이용한 GC 분석

Page 186: Java Performance Tuning

186 - Internal Use Only -

OutOfMemory 문제

GC 모니터링 툴을 이용한 그래프 보기

• IBM Garbage Collector Analyzer 를 이용한 GC 분석

Page 187: Java Performance Tuning

187 - Internal Use Only -

OutOfMemory 문제

GC 모니터링 툴을 이용한 그래프 보기

• VisualVM을 이용한 GC 모니터링

Page 188: Java Performance Tuning

188 - Internal Use Only -

OutOfMemory 문제

GC 모니터링 툴을 이용한 그래프 보기

• Java Mission Control (Java+7)

Page 189: Java Performance Tuning

189 - Internal Use Only -

OutOfMemory 문제

SUN Heap Dump 분석

• SUN JDK 1.6

OOM시 HeapDump가 생성되도록 설정

-XX:+HeapDumpOnOutOfMemoryError

JMap을 이용한 수동 생성

jmap –dump:format=b,file=test.jmap <PID>

HeapAnalyzer Tool을 이용한 분석

Page 190: Java Performance Tuning

190 - Internal Use Only -

OutOfMemory 문제

SUN Heap Dump 분석

• SUN JDK 1.6

IBM HeapDump Analyzer Tool (HA)를 이용한 Heap Dump 를 분석

1. Heap Dump 상에서 가장 많이 차지하고 있는 Object를 확인

2. 해당 Object의 reference를 추적

Page 191: Java Performance Tuning

191 - Internal Use Only -

OutOfMemory 문제

SUN Heap Dump 분석

• SUN JDK 1.6

Memory Analyzer Tool (MAT)를 이용한 Heap Dump 를 분석

IBM Heap Analyzer 와 마찬가지 방식으로 문제 분석

Page 192: Java Performance Tuning

192 - Internal Use Only -

OutOfMemory 문제

OutOfMemory 분석의 예 – 1. GC 분석

Page 193: Java Performance Tuning

193 - Internal Use Only -

OutOfMemory 문제

OutOfMemory 분석의 예 – 2. GC 분석

OutOfMemory 발생전 Old Full GC 다수 발생함

평상시 사용 메모리는 높지 않은 상태

Page 194: Java Performance Tuning

194 - Internal Use Only -

OutOfMemory 문제

OutOfMemory 분석의 예 – 3. 장애후 진행/조치한 내용

• Web Server, WAS Server 머신의 Time 동기화 작업

• Web서버 Error Log, Access Log분석

• OutOfMemory를 유발하는 Application을 찾음 - EAI or SOA(XML)

• 장애 발생 직후 Thread Dump분석

작업 진행 중인 Application에 대한 List up

List한 Application에 대한 우선적인 점검

• Heap Dump 분석

과다 메모리 점유 Object 객체 확인

Page 195: Java Performance Tuning

195 - Internal Use Only -

OutOfMemory 문제

OutOfMemory 체크 리스트

• OOM이 어디에서 발생하는지 체크

Java heap

Native 메모리

• 메모리 사용량 데이터 수집 및 분석

Java Heap에 대해선 verbose GC를 사용

Native 메모리에 대해선 Virtual Process Mem 사이즈를 모니터링

메모리 Leak인지 체크

Page 196: Java Performance Tuning

196 - Internal Use Only -

OutOfMemory 문제

Java Heap OOM 체크리스트

• 애플리케이션 기능에 대한 체크

Long lived objects

Caching

최근에 변경된 부분이나 새로 추가된 사용자

추가된 애플리케이션이 없는지 체크

• 상세한 OOM 체크

Heap의 메모리를 dump받아 분석

Page 197: Java Performance Tuning

197 - Internal Use Only -

OutOfMemory 문제

Java Native OOM 체크리스트

• 서버의 물리적인 메모리가 모자라진 않는지 체크

• OS의 프로세스에 대한 Virtual 메모리 Limit을 체크

• 프로세스의 Virtual 메모리를 주기적으로 체크

• 물리적인 메모리가 부족하면 메모리 증설 or 서버 증설

• 가능하면 JVM Heap 크기를 줄이는 방법도 체크

• JNI 모듈이 사용되는지 체크

• JVM Core를 받아 분석하는 방법 OS/JVM 벤더에 Escalation

• 일반적으로

사용자 JNI 모듈 > JVM > OS 순으로 발생 가능성이 높음

Page 198: Java Performance Tuning

198 - Internal Use Only -

OutOfMemory 문제

Linux 시스템의 메모리 관리에 대해

• Linux 메모리 관리방식

• http://www.puschitz.com/TuningLinuxForOracle.shtml

• Linux에서는 성능 향상을 목적으로 Disk I/O를 줄이기 위해 가용한 메모리를 최대한 사

용(used)

• 첫 줄의 used는 필요 시 즉시 해제하여 사용할 수 있는 buffers 및 cached등을 포함

• 따라서 첫 줄 used는 일정 시간 후 메모리의 95% 이상이 됨

• Linux에서의 가용 메모리는 두번 째 줄의 free를 사용해야 함

Page 199: Java Performance Tuning

Server Crash 문제

Page 200: Java Performance Tuning

200 - Internal Use Only -

목차

JVM Core?

Server Core의 증상 및 분석방법

core 파일이 안 만들어지는 경우

core 파일 분석

JVM Crash의 예

Page 201: Java Performance Tuning

201 - Internal Use Only -

Server Crash 문제

JVM Core?

• JVM 프로세스가 Crash되면 core파일이 남는다

• core파일에는 장애시점의 프로세스의 snapshot이 남아있다

• UNIX에서는 core 파일이 프로세스를 실행한 디렉토리에 남는다

• Windows에서는 C:\Documents and Settings\All

Users\Documents\DrWatson 디렉토리에 남는다

• Java 코드에서는 JVM을 Crash 시킬수 없다

• JVM Crash시킬 수 있는 것

JVM 자체의 Native 코드

JNI 코드(WLS의 경우엔 Performance Pack, Type 2 JDBC Driver)

혹은 사용자 JNI 코드

Page 202: Java Performance Tuning

202 - Internal Use Only -

Server Crash 문제

Server Core의 증상 및 분석 방법

• 증상

WAS Server Crash

JVM Crash

머신 Crash

HotSpot Error

• 분석방법

core파일이 생성되었는지 체크

생성되지 않았다면 생성되도록 설정(OS)

core파일로 발생할 당시의 Crash원인을 분석

Page 203: Java Performance Tuning

203 - Internal Use Only -

Server Crash 문제

core 파일이 안 만들어질 경우

• core 파일 사이즈 limit을 체크한다

ulimit –c 로 확인

Solaris의 경우 /etc/system의 sys:coredumpsize 확인

Linux의 경우 /etc/security/limits.conf

HP-UX의 경우 maxdsiz

OS 엔지니어에게 요청한다

• core dump를 받는 명령어

gcore [–o filename] <PID>

• JVM이 Crash될 때 Thread Dump를 받을 수 있도록 설정

Crash되거나 할 때 Prompt로 남아 있어 장애 조치를 취할 수 있다

Sun, HP JVM

-XX:+ShowMessageBoxOnError

JRockit JVM

-Djrockit.waitonerror

Page 204: Java Performance Tuning

204 - Internal Use Only -

Server Crash 문제

분석을 위한 디버깅 도구

• gdb(GNU Project Debugger) – Crash 상황의 프로그램의 수행 상황을 디버깅

http://www.gnu.org/software/gdb

• AIX에서는 Crash시 javacore<PID>.<ID Number>.txt 파일 생성

dbx,

pstack

pmap

procstack

procmap

gdb

pstack

pmap

Page 205: Java Performance Tuning

205 - Internal Use Only -

Server Crash 문제

장애에 대한 Core 파일 분석 방법

• File을 명령을 이용한 정보 확인

• gdb를 이용한 분석을 수행

[jboss@KVM2 node1]$ file core.5622 core.5622: LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from ':MaxPermSize=256m -Dsun.'

$ gdb <path to java command>/java corefile (gdb) where (shows a summary of the stack) (gdb) thr (switch threads or show the current thread) (gdb) info thr (inquire about existing threads) (gdb) thread apply 1 bt (backtrace to thread #1) (gdb) quit (exit gdb)

Page 206: Java Performance Tuning

206 - Internal Use Only -

Server Crash 문제

pstack, pmap

• pstack <pid>

• pmap <pid>

[jboss@KVM2 node1]$ pstack 5622 Thread 116 (Thread 0xb809cb90 (LWP 5623)): #0 0xb80c8424 in __kernel_vsyscall () #1 0x0089b105 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0 #2 0x0089b912 in pthread_cond_wait@GLIBC_2.0 () from /lib/libpthread.so.0 #3 0x065060c9 in os::PlatformEvent::park () #4 0x064ed92d in Monitor::IWait () #5 0x064edf21 in Monitor::wait () #6 0x065d22e7 in Threads::destroy_vm () #7 0x0639ef02 in jni_DestroyJavaVM () #8 0x0664c0c0 in ?? ()

[jboss@KVM2 node1]$ pmap 5622 5622: ava -D[Standalone] -XX:+UseCompressedOops -server -Xms1024m -Xmx1024m -XX:MaxPermSize=256m -Xloggc:log/gc_20131122201158.log -XX:+UseParallelGC -XX:+ExplicitGCInvoke …중략 00682000 88K r-x-- /lib/libnsl-2.9.so 00698000 4K r-x-- /lib/libnsl-2.9.so 00699000 4K rwx-- /lib/libnsl-2.9.so 0069a000 8K rwx-- [ anon ] 006c4000 128K r-x-- /lib/ld-2.9.so

Page 207: Java Performance Tuning

207 - Internal Use Only -

Server Crash 문제

Core 파일 분석의 예 – 1. 장애 시점 확인

• hs_er 로그를 통한 장애 시점 확인

[root@portal02 core_dump]# vi hs_err_pid5102.log # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x0000003672c07b35, pid=5102, tid=47705698814672 # # JRE version: 6.0_30-b12 # Java VM: Java HotSpot(TM) 64-Bit Server VM (20.5-b03 mixed mode linux-amd64 compressed oops) # Problematic frame: # C [libpthread.so.0+0x7b35] pthread_join+0x125 # # An error report file with more information is saved as: # /JBOSS/jboss-eap-5.1/domains/portal02/hs_err_pid5102.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # /JBOSS/jboss-eap-5.1/jboss-as/bin/run.sh: line 289: 5102 Aborted (core dumped) "/usr/java/jdk1.6.0_30/bin/java" -Xbootclasspath/p:/JBOSS/pineapp/appagent/lib/pinejdks6-3.5.0.jar:/JBOSS/pineapp/appagent/lib/pineagent-3.5.0.jar:/JBOSS/pineapp/appagent/lib/pineext-3.5.0.jar:/JBOSS/jboss-eap-5.1/jboss-as/common/lib/ojdbc6.jar …중략 SIGUSR1: SIG_DFL, sa_mask[0]=0x00000000, sa_flags=0x00000000 SIGUSR2: [libjvm.so+0x711210], sa_mask[0]=0x00000000, sa_flags=0x10000004 SIGHUP: SIG_IGN, sa_mask[0]=0x00000000, sa_flags=0x00000000 SIGINT: SIG_IGN, sa_mask[0]=0x00000000, sa_flags=0x00000000 SIGTERM: [libjvm.so+0x710e10], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004 SIGQUIT: [libjvm.so+0x710e10], sa_mask[0]=0x7ffbfeff, sa_flags=0x10000004

Page 208: Java Performance Tuning

208 - Internal Use Only -

Server Crash 문제

Core 파일 분석의 예 – 2. gdb

• gdb 를 이용 jvm crash 위치 및 thread 번호 확인

[root@portal02 core_dump]# gdb /usr/java/jdk1.6.0_30/bin/java -c /tmp/core.java.5472 .. [New Thread 5473] [New Thread 5472]

#1 where 를 이용한 jvm crash 위치 확인 (gdb) where #0 0x00002aaaaf4f35bd in Java_java_net_SocketOutputStream_socketWrite0 () from /usr/java/jdk1.6.0_30/jre/lib/amd64/libnet.so #1 0x00002aaaab78d251 in ?? ()

#2 info thr 를 이용 thread 번호 확인 (gdb) info thr 387 Thread 5472 0x0000003672c07b35 in ?? () 386 Thread 5473 0x0000003672c0aee9 in ?? () …중략 3 Thread 17583 0x0000003672c0b150 in ?? () 2 Thread 17652 0x0000003672c0b150 in ?? () * 1 Thread 12056 0x00002aaaaf4f35bd in ?? () jvm core 발생 thread 정보

Page 209: Java Performance Tuning

209 - Internal Use Only -

Server Crash 문제

Core 파일 분석의 예 – 3. pstack

• gdb thread 정보를 통해 12056을 맵핑

[root@portal02 core_dump]# /usr/java/jdk1.6.0_30/bin/jstack /usr/java/jdk1.6.0_30/bin/java /tmp/core.java.5472 … 중략 ## gdb thread 번호 * 1 Thread 12056 0x00002aaaaf4f35bd in ?? ()

#3 stack tread 번호 맵핑 후 thread 분석 Thread 12056: (state = IN_NATIVE) - org.apache.catalina.core.ApplicationDispatcher.doInclude(javax.servlet.ServletRequest, javax.servlet.ServletResponse) @bci=260, line=543 (Interpreted frame) - org.apache.catalina.core.ApplicationDispatcher.include(javax.servlet.ServletRequest, javax.servlet.ServletResponse) @bci=55, line=480 (Interpreted frame) - com.saltware.enview.aggregator.impl.EnviewPageAggregatorImpl.build(com.saltware.enview.request.RequestContext) @bci=936, line=311 (Interpreted frame) - com.saltware.enview.aggregator.EnviewAggregatorValve.invoke(com.saltware.enview.request.RequestContext) @bci=5, line=51 (Interpreted frame) - com.saltware.enview.pipeline.EnviewPipelineImpl.invoke(com.saltware.enview.request.RequestContext, int) @bci=7, line=144 (Compiled frame) - com.saltware.enview.engine.EnviewEngine.service(com.saltware.enview.request.RequestContext) @bci=319, line=285

Page 210: Java Performance Tuning

Too Many Open Files 문제

Page 211: Java Performance Tuning

211 - Internal Use Only -

목차

File Descriptor란?

FD관련 OS 파라미터

TCP State Diagram

Too Many Open Files가 발생하는 이유

현상

원인 분석

Page 212: Java Performance Tuning

212 - Internal Use Only -

Too Many Open Files 문제

File은 언제 Open되는가?

• 파일이 생성되고 오픈되는 시점

JVM이 클래스를 읽을 때

JVM내의 애플리케이션이 필요한 설정 파일들을 읽을 때

새로운 Socket 연결을 만들때

브라우저가 서버에 접속할 때

• 사용자나 로드가 많고 큰 사이즈의 애플리케이션은 동시에 많은 파일을 오픈해야 함

• POSIX계열 OS에서는 File Descriptor라고 말함

• Windows OS에서는 File Handle이라고 말함

• 0 : stdin, 1 : stdout, 2 : stderr

• FD(File descriptor)는 Files, Directory, Character Device, Socket, Pipe를 Reference함

Page 213: Java Performance Tuning

213 - Internal Use Only -

Too Many Open Files 문제

OS FD관련 파라미터

• OS의 파일 limit

총 File Descriptor개수를 지정가능

하나의 프로세스에서 열수 있는 최대 FD개수를 지정가능

• OS 커널 파라미터

Windows: handles (기본 16,384)

Solaris: rlim_fd_cur and rlim_fd_max

기본 65,536, ulimit로 변경

HPUX: nfile, maxfiles and maxfiles_lim

nfile = ((NPROC*2)+1000), NPROC=((MAXUSERS*5)+64)

Linux: nofile and file-max

fd : limits /etc/security/limits.conf

System FD limits /etc/rc.d/rc.local

AIX: OPEN_MAX

fd limits : /etc/security/limits (기본 2000)

Page 214: Java Performance Tuning

214 - Internal Use Only -

Too Many Open Files 문제

언제 FD를 Release하나?

• 파일이 Close() 될때나 프로세스가 종료되면 FD가 Release된다.

• 모든 연관된 FD는 반드시 close되어야 다시 쓸수 있다.

• TCP 소켓 FD는 TIME_WAIT가 끝날때 까지는 close되지 않는다.

• closed된 FD는 새로 파일을 오픈되면 재사용된다.

Page 215: Java Performance Tuning

215 - Internal Use Only -

Too Many Open Files 문제

TCP State Diagram

Page 216: Java Performance Tuning

216 - Internal Use Only -

Too Many Open Files 문제

Too Many Open Files 에러가 발생하는 상황

• 프로그램에서 파일이 FD를 release하지 않는 경우

• TCP 소켓이 TIME_WAIT에서 종료되지 않아 release되지 않는 경우

• 파일을 연 FD는 반드시 프로그램에서 명시적으로 close해야 하나 하지

않은 경우

Page 217: Java Performance Tuning

217 - Internal Use Only -

Too Many Open Files 문제

증상

java.io.IOException: Too many open files at java.lang.UNIXProcess.forkAndExec(Native Method) at java.lang.UNIXProcess.(UNIXProcess.java:54) at java.lang.UNIXProcess.forkAndExec(Native Method) at java.lang.UNIXProcess.(UNIXProcess.java:54) at java.lang.Runtime.execInternal(Native Method) at java.lang.Runtime.exec(Runtime.java:551)

java.net.SocketException: Too many open files at java.net.PlainSocketImpl.accept(Compiled Code) at java.net.ServerSocket.implAccept(Compiled Code)

파일이 많이 열린 경우

소켓이 많이 열린 경우

• 로그에 아래와 같은 Exception이 발생함.

Page 218: Java Performance Tuning

218 - Internal Use Only -

Too Many Open Files 문제

설정 확인

• ulimit –a

• 각 OS 별도 출력되는 내용이 다를 수 있음.

[jboss@KVM2 node1]$ ulimit –a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 62338 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 35565 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 1024 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited

Page 219: Java Performance Tuning

219 - Internal Use Only -

Too Many Open Files 문제

Linux의 limit 설정방법

• /etc/security/limits.conf

[jboss@KVM2 node1]$ vi /etc/security/limits.conf root soft nofile 65536 root hard nofile 65536 root soft nproc 20680 root hard nproc 20680 root soft stack unlimited root hard stack unlimited jboss - nofile 65536 jboss - memlock 10240

Page 220: Java Performance Tuning

220 - Internal Use Only -

Too Many Open Files 문제

문제 분석 방법 • lsof

• list open files 명령을 이용한 분석

사용법 : lsof –p <PID> [jboss@KVM2 /opt/servers/standalone_ha_11/bin]$ ps -ef|grep java jboss 8143 8016 0 20:11 pts/0 00:00:12 java -D[Standalone] -XX:+UseCompressedOops -server -Xms1024m -Xmx1024m -XX:MaxPermSize=256m -Xloggc:log/gc_20131122201158.log -XX:+UseParallelGC -XX:+ExplicitGCInvoke [jboss@KVM2 /opt/servers/standalone_ha_11/bin]$ lsof -p 8143 lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /root/.gvfs Output information may be incomplete. COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 8143 jboss cwd DIR 253,1 4096 2099462 /opt/servers/standalone_ha_11/bin java 8143 jboss rtd DIR 253,1 4096 2 / java 8143 jboss txt REG 253,4 9624 166988 /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/bin/java java 8143 jboss mem REG 253,1 156872 2490370 /lib64/ld-2.12.so java 8143 jboss mem REG 253,4 55400 146935 /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/amd64/jli/libjli.so java 8143 jboss mem REG 253,1 1922152 2490375 /lib64/libc-2.12.so java 8143 jboss mem REG 253,1 22536 2490388 /lib64/libdl-2.12.so java 8143 jboss mem REG 253,1 145720 2490382 /lib64/libpthread-2.12.so java 8143 jboss mem REG 253,1 91096 2490386 /lib64/libz.so.1.2.3 …중략 java 8143 jboss mem REG 253,4 989840 393419 /usr/lib64/libstdc++.so.6.0.13

Page 221: Java Performance Tuning

221 - Internal Use Only -

Too Many Open Files 문제

문제 분석 방법 • lsof -p <PID> | wc –l 명령어를 통해 과도한 File Open이 있는지 확인

• Windows의 경우엔 sysinternal의 handle 유틸리티를 이용

http://technet.microsoft.com/en-us/sysinternals/default.aspx handle –p java sysinternal의 Process Explorer를 이용한 GUI에서 handle을 볼 수 있음

[jboss@KVM2 /opt/servers/standalone_ha_11/bin]$ lsof -p 8143 | wc -l lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /root/.gvfs Output information may be incomplete. 565

D:\Jboss Tunnign_Tool\Handle>handle -p java Handle v3.51 Copyright (C) 1997-2013 Mark Russinovich Sysinternals - www.sysinternals.com ------------------------------------------------------------------------------ java.exe pid: 13608 C: File (RW-) D:\usr\local\jboss-eap-6.1.0\bin 44: Section \Sessions\1\BaseNamedObjects\mchLLEW2$3528 48: File (RWD) D:\Java\jdk1.6.0_37\bin 84: Section \Sessions\1\BaseNamedObjects\NamedBuffer, mix, Process $00003528, API $0000000080000000 100: Section \Sessions\1\BaseNamedObjects\windows_shell_global_counters 120: Section \Sessions\1\BaseNamedObjects\AutoUnhookMap$00003528$f3430000

Page 222: Java Performance Tuning

222 - Internal Use Only -

Too Many Open Files 문제

문제 분석 방법

• netstat을 이용한 소켓 모니터링

$ netstat –na | grep <사용포트>

$ netstat –na Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:4544 0.0.0.0:* LISTEN ……

Page 223: Java Performance Tuning

223 - Internal Use Only -

Too Many Open Files 문제

문제 해결 방법

• lsof를 이용해 어떤 파일이 열러 있는지 주기적으로 분석한다

• 애플리케이션에서 과도하게 많이 사용되는 FD가 없는지 체크한다

• 특정한 종류의 파일이 많이 열렸다면 FD를 close안하는 애플리케이션이 있는지 체크한다.

• 필요한 FD만 열려 있다면, OS의 FD limit가 부족하지 않는지 체크한다.

• 부족하면 먼저 user limit를 늘리고 모니터링

• 이것도 부족하면 OS limit를 늘리고 모니터링 한다

• 계속해서 FD가 늘어나는 상황이면 다음을 모니터링 한다

애플리케이션에서 파일이 정상적으로 close되는지

불필요한 파일이 생성되지는 않는지

class 파일도 하나의 FD를 점유하기 때문에 class 파일로 사용하면 jar로 묶어서 배포한다

TIME_WAIT가 너무 많은 경우 사용자가 많은 과부하 상황일 수 있음

• 문제가 되는 애플리케이션을 발견하면 Thread dump를 받아 분석하는 것도 좋은 방법

• TIME_WAIT이 많으면 OS의 TCP TIME_WAIT값을 줄여서 적용

Page 224: Java Performance Tuning

JDBC 문제

Page 225: Java Performance Tuning

225 - Internal Use Only -

목차

JDBC란

JDBC Driver의 Type

Oracle RAC(TAF, CTF)

JDBC Driver의 선택

JDBC Connection Pool 설정

주요 오류

주요 Oracle Error

Connection Leak

OutOfMemory

Page 226: Java Performance Tuning

226 - Internal Use Only -

JDBC 문제

JDBC란

• JDBC가 하는 일

Database 연결

SQL 문장 전송

결과 처리

Page 227: Java Performance Tuning

227 - Internal Use Only -

JDBC 문제

JDBC Driver의 Type

Type I “Bridge”

Type II “Native”

Type III “Middleware”

Type IV “Pure”

JDBC

ODBC ODBC Driver

CLI (.lib)

Middleware Server

Page 228: Java Performance Tuning

228 - Internal Use Only -

JDBC 문제

Oracle RAC

Oracle RAC Nodes

Page 229: Java Performance Tuning

229 - Internal Use Only -

JDBC 문제

CTF & TAF

구분 내용 고려사항

CTF(Connection Time FailOver)

데이터베이스로 접속하는 순간에 Server, DB, Listener등이 가용하지 않을 경우에 다른 쪽 Server로 접속하는 것을 말함.

OCI를 사용하지 않는프로그램은 매뉴얼 하게 Logic를 구사해야 한다.

TAF(Transparent Application Failover)

접속 후 데이터베이스 사용 중에 DB나 Session이 장애가 발생 했을 경우에 다른 node로 접속하여 진행하던 작업을 계속할 수 있도록 하는 것을 말함.

OCI를 사용 할 경우에는 오라클에서 CallBack method를 지원하나OCI를 사용하지 않을 경우에는 Logic으로 구사해야 함

FailOver 방법 TAF에서제공하는 Failover 방법들을 말함. Mode : session, select Method : Basic, Preconnect

Language별 모든 programming language를 TAF가 지원 하지 는 않고 OCI를 사용하는 language만을 지원한다.

장애 유형별 사용 여부 장애 유형별 TAF를 사용해야 할지 결정한다.

Page 230: Java Performance Tuning

230 - Internal Use Only -

JDBC 문제

JDBC Driver의 선택

• JDBC Driver의 선택

항상 최신 버전의 JDBC Driver 사용

Oracle의 경우 RAC TAF를 사용하지 않는다면 Thin 드라이버를 사용

Oracle Database 최신 버전은 – 12.1.0.1

ojdbc7.jar JDK 1.7용, ojdbc6.jar JDK 1.6용

ojdbc5.jar JDK 1.5, ojdbc14.jar JDK 1.4용

*_g.jar 파일 디버그정보를 포함한 드라이버

OCI 드라이버 libocijdbc<major_version_id>.so 버전번호가 표시됨

Page 231: Java Performance Tuning

231 - Internal Use Only -

JDBC 문제

JDBC Connection Pool

WAS의 JDBC connection pool:

JDBC를 통한 Database연결 속도가 느리기 때문에 연결을 미리 맺은

상태에서 Pool을 만들어 이를 애플리케이션에 제공

Pool의 Connection은 재사용하며, 사용량에 따라 Pool내의

Connection개수를 가변적으로 활용(Shrink).

애플리케이션에서는 JNDI 트리에 바인딩된 DataSource를 통해 접근

WAS는 prepared, callable statement를 캐쉬 할 수 있습니다.

Statement Cache [WAS DB]간의 overhead 감소

애플리케이션의 특성에 따라 Cache 크기를 조절 (일반적으로 100정도)

Page 232: Java Performance Tuning

232 - Internal Use Only -

JDBC 문제

JDBC관련 주요 오류

• 주요 오류 메시지

ResourceException

SQLException

OutOfMemoryError

• 서버 Crash

서버 crash 관련 내용 참조

• 서버 Hang, 애플리케이션 Hang

Thread Dump 분석(서버 Hang 관련 내용 참조)

• 데이터베이스 Restart 이후 연결 Refresh 문제

Page 233: Java Performance Tuning

233 - Internal Use Only -

JDBC 문제

주요 Oracle 오류 메시지

• ORA-01017: invalid username/password; logon denied

데이터베이스 사용자 ID/패스워드를 확인

• java.sql.SQLException: IO exception: The Network Adapter could not establish the

connection

DB 연결이 안되는 경우(JDBC Connection URL설정을 확인)

Oracle DB Listener를 확인

• ORA-12154: TNS could not resolve service name

TNS 리스너의 정보와 연결 설정 정보 확인

• ORA-00020 - maximum number of processes (300) exceeded

오라클의 MAX Session을 초과한 경우(init.ora에서 설정)

JDBC Connection Leak이 아닌지 의심해 봐야함

• java.sql.SQLException: ORA-01000: maximum open cursors exceeded

JDBC Connection Leak을 체크해야 함

DBA에게 DBA_PENDING_TRANSACTIONS 확인을 부탁

Page 234: Java Performance Tuning

234 - Internal Use Only -

JDBC 문제

JDBC Connection Leak

• JBoss에서 JDBC Connection Leak 디버깅

deploy/jbossjca-service.xml

• WLS에서는 ConnLeakProfilingEnabled=true로 설정

<!-- | The CachedConnectionManager is used partly to relay started UserTransactions to | open connections so they may be enrolled in the new tx. --> <mbean code="org.jboss.resource.connectionmanager.CachedConnectionManager" name="jboss.jca:service=CachedConnectionManager"> <depends optional-attribute-name="TransactionManagerServiceName">jboss:service=TransactionManager</depends> <!-- Enable connection close debug monitoring --> <attribute name="Debug">true</attribute> </mbean>

Page 235: Java Performance Tuning

235 - Internal Use Only -

JDBC 문제

OutOfMemory

• JDBC관련 OutOfMemory

주로 대용량 쿼리를 수행할 때 발생되는 경우

애플리케이션에서 페이징 처리

레포팅을 위해 모든 데이터를 한꺼번에 쿼리하는 경우

검색등에서 페이지내 Row 개수를 누락한 경우

Heap Dump를 통해 분석가능

Page 236: Java Performance Tuning

236 - Internal Use Only -

• JDBC Driver Type4는 소켓을 사용하여 DBMS에 연결하는 방식

• QueryTimeout은 정상적으로 소켓 연결을 맺고 있을 때에만 유효

• 네트워크 장애 상황을 대비하려면 JDBC 드라이버에 있는 SocketTimeout을 설정

• OS Level의 KeepAlive등을 튜닝

• 이미지 참조 – NHN 개발자 블로그 – [JDBC Internal – 타임아웃의 이해]

JDBC 문제

WAS와 DBMS의 통신 시 타임아웃 계층

Page 237: Java Performance Tuning

237 - Internal Use Only -

OPEN

SHARE

CONTRIBUTE

ADOPT

REUSE