java performance and trouble shooting
TRANSCRIPT
OPEN
SNS
Java Performance
Written by Jongha & Anna
Why & What Conclusion How &
Implement
당신의 어플리케이션은 안 녕 하 십 니 까 ?
OPEN
SNS Why & What Conclusion How &
Implement
여러가지 성능 문제와 프로세스 진단
다양한 툴을 활용하여 문제 해결
각각의 Tool 비교
Outline
OPEN
SNS Why & What Conclusion How &
Implement
Troubleshooting
문제 정의 해결 방안
체계적 접근 원인 제거
OPEN
SNS Why & What Conclusion How &
Implement
Practice makes perfect Have a good set of tools
How To Become A Good Troubleshooter
OPEN
SNS Why & What Conclusion How &
Implement
We Need an Application
OPEN
SNS Why & What Conclusion How &
Implement
Application
OPEN
SNS Why & What Conclusion How &
Implement
We have our Application
SHOULD WE JUST JUMP INTO TROUBLESHOOTING?
OPEN
SNS Why & What Conclusion How &
Implement
What is Trouble?
OPEN
SNS Why & What Conclusion How &
Implement
What is Trouble?
OPEN
SNS Why & What Conclusion How &
Implement
What is Normal?
분노의 트러블슈팅 : 더 세븐
Transaction Time 500ms 미만으로 찍어주겠어!!
OPEN
SNS Why & What Conclusion How &
Implement
Errors
어플리케이션 에러
What Are The Stats?
Application Response Time
응답 시간
Database Response Time
응답 시간
Thread State
스레드 상태
Garbage Collection
GC 수행시간
Memory Allocation
Heap and PermGen
OPEN
SNS Why & What Conclusion How &
Implement
How To Gather The Stats
Logs Profiles core JDK tools JMS Metrix Application Performance Monitoring Tools(APM) Framework / App Server Monitoring Tools
OPEN
SNS Why & What Conclusion How &
Implement
Basic Information
Tools Overview Installation Is It Free Include With JDK
nGrinder APM solution restart app with
agent yes no
JMap/JHat prints memory
map no yes yes
JVisualVM profiler no yes yes
JStack prints thread
dump no yes yes
Scouter APM solution restat app with
agent yes no
GC Memory
OPEN
SNS Why & What Conclusion How &
Implement
Data In Tool
Tools App
Response Time
DB Response
Time
Error Info
Thread Info
nGrinder Yes Yes Yes Yes Yes Yes
JMap/JHat Yes
JVisualVM Yes Yes Yes Yes
JStack Yes
Scouter Yes Yes Yes Yes Yes Yes
OPEN
SNS Why & What Conclusion How &
Implement
Start Trouble Shooting
OPEN
SNS Why & What Conclusion How &
Implement
Let’s Investigate!
OPEN
SNS Why & What Conclusion How &
Implement
nGrinder
OPEN
SNS Why & What Conclusion How &
Implement
nGrinder System Architecture
스크립트 생성
테스트 설정 및 진행
상세결과보기 결과 리포트
TPS
Heap Size
Used Heap Size
CPU
Memory
GC
OPEN
SNS Why & What Conclusion How &
Implement
Basic Information
Tools Overview Installation Is It Free Include With JDK
nGrinder APM solution restart app with
agent yes no
JMap/JHat prints memory
map no yes yes
JVisualVM profiler no yes yes
JStack prints thread
dump no yes yes
Scouter APM solution restat app with
agent yes no
GC Memory
OPEN
SNS Why & What Conclusion How &
Implement
Data In Tool
Tools App
Response Time
DB Response
Time
Error Info
Thread Info
nGrinder Yes Yes Yes Yes Yes Yes
JMap/JHat Yes
JVisualVM Yes Yes Yes Yes
JStack Yes
Scouter Yes Yes Yes Yes Yes Yes
OPEN
SNS Why & What Conclusion How &
Implement
WHY? 메모리 구조를 알아야 하는가!!
메모리
: 프로그램을 실행하기 위한 데이터 및 명령어를 저장하는 공간
메모리 관리에 따라 성능이 좌우되며, 속도 저하, HANG 현상 등이 발생 효율적인 사용으로 최고의 성능
OPEN
SNS Why & What Conclusion How &
Implement
Java Virtual Machine
스택기반의 가상머신 OS에 독립적 메모리 관리 기능 (GC : Garbage Collection)
OPEN
SNS Why & What Conclusion How &
Implement
Java 프로그램 실행 구조
OPEN
SNS Why & What Conclusion How &
Implement
JVM 기본 수행 과정
OPEN
SNS Why & What Conclusion How &
Implement
Classloader
Classloader
Java Virtual Machine
Class
Class
Class
Class
Class
OPEN
SNS Why & What Conclusion How &
Implement
Classloader
Classloader
Class
Class
Class
Class
Car
Java Virtual Machine
Car a = new Car();
a
OPEN
SNS Why & What Conclusion How &
Implement
Classloader
Classloader
Class
Class
Food
House
Car
Java Virtual Machine
Car a = new Car(); Car b = new Car(); House c = new House(); Food d = new Food();
a
b
c
d
OPEN
SNS Why & What Conclusion How &
Implement
Classloader
Classloader
Class
Class
Food
House
Car
Java Virtual Machine
a
b
c
d
Object
Object
Object
Object
Object
Object Object Object
Object
Object
Object
Object
Object Object
Object
Object
Object
OPEN
SNS Why & What Conclusion How &
Implement
OOME : Out Of Memory Error
Baaam....Explosion
OPEN
SNS Why & What Conclusion How &
Implement
OOME : Out Of Memory Error
OPEN
SNS Why & What Conclusion How &
Implement
Runtime Data Area
PC Register JVM Stack Native Method Stack
Heap Method Area Runtime Constant Pool
OPEN
SNS Why & What Conclusion How &
Implement
Heap Area
Heap 영역은 Young, Old(Tenured), Perm과 같이 3가지 영역으로 구분
Young 영역은 1개의 Eden과 2개의 Survivor 영역으로 구성
Perm 영역은 컴파일된 코드가 올라가는 영역
Heap 영역에서 메모리를 정리하는 과정을 Garbage Collection(GC)라고 함
OPEN
SNS Why & What Conclusion How &
Implement
Garbage Collector
Classloader
Class
Class
Food
House
Car
Java Virtual Machine
a
b
c
d
Object
Object
Object
Object
Object
Object Object Object
Object
Object
Object
Object
Object
Object
Object
finalize
finalize
finalize
finalize
finalize
finalize
finalize finalize
OPEN
SNS Why & What Conclusion How &
Implement
Garbage Collector
Classloader
Class
Class
Food
House
Java Virtual Machine
d
Object
Object
Object
Object
Object
Object Object Object
Object
Object
Car finalized
OPEN
SNS Why & What Conclusion How &
Implement
메모리 크기와 관련된 GC 옵션
구 분 옵 션 설 명
Heap 영역 크기
-Xms JVM 시작 시 Heap 영역 크기
-Xmx 최대 Heap 영역 크기
New 영역 크기
-XX:NewRatio New 영역과 Old 영역의 비율
-XX:NewSize New 영역의 크기
-XX:SurvivorRatio Eden 영역과 Survivor 영역의 비율
OPEN
SNS Why & What Conclusion How &
Implement
객체 할당 과정
1. 처음 Heap 상태
2. 객체가 생성된 상태 : Eden 영역에 먼저 생성
3. Eden GC 발생 후
4. 할당된 Survivor1 영역이 GC 발생 : Eden, Survivor1 객체가 모두 Survivor2로 이동
5. 위 과정 반복 수행 후 : 오래된 객체는 OLD Area로 이동
Minor GC
Minor GC Major GC or Full GC
OPEN
SNS Why & What Conclusion How &
Implement
Garbage Collection 방식
Serial GC Parallel GC Parallel Old GC Concurrent Mark & Sweep GC G1(Garbage First) GC
OPEN
SNS Why & What Conclusion How &
Implement
Serial GC (-XX:+UseSerialGC)
Young 영역에서의 GC는 앞 장에서 설명한 방식을 사용 Old 영역의 GC는 mark-sweep-compact라는 알고리즘을 사용 1. Old 영역의 살아있는 객체를 식별(Mark)
2. Heap 앞 부분부터 확인하여 살아있는 것만 남김(Sweep)
3. 각 객체들이 연속되게 쌓이도록 협의 가장 앞 부분부터 채워서 객체가 존재하는 부분과 객체가 없는 부분으로 나눔(Compact)
OPEN
SNS Why & What Conclusion How &
Implement
Parallel GC (-XX:+UseParallelGC)
Serial GC와 기본적인 알고리즘은 같음 Serial GC는 GC를 처리하는 Thread가 하나인 것에 비해 Parallel GC는 GC를 처리하는 Thread가 여러 개 Serial GC보다 빠르게 객체를 처리할 수 있음 Parallel GC는 메모리가 충분하고 코어의 개수가 많을때 유리
Serial GC
VS
Parallel GC
OPEN
SNS Why & What Conclusion How &
Implement
Parallel Old GC(-XX:+UseParallelOldGC)
Parallel Old GC는 JDK 5 update 6부터 제공한 GC 방식 Parallel GC와 비교하여 Old 영역의 GC 알고리즘만 다름 이 방식은 Mark-Summary-Compaction 단계를 거침 Summary 단계는 앞서 GC를 수행한 영역에 대해서 별도로 살아있는 객체를 식별한다는 점에서 Mark-Sweep-Compaction 알고리즘의 Sweep 단계와 다르며 약간 더 복잡한 단계를 거침
OPEN
SNS Why & What Conclusion How &
Implement
CMS GC (-XX:+UseConcMarkSweepGC)
초기 Initial Mark 단계에서는 클래스로더에서 가장 가까운 객체 중 살아있는 객체만 찾음 멈추는 시간이 매우 짧다 Concurrent Mark 단계에서는 방금 살아있다고 확인한 객체에서 참조하고 있는 객체를 따라가며 확인 (다른 스레드가 실행중인 상태에서 동시 진행) Remark 단계에서는 Concurrent Mark 단계에서 새로 추가되거나 참조가 끊긴 객체를 확인 Concurrent Sweep 단계에서는 쓰레기를 정리하는 작업 실행 (다른 스레드가 실행중인 상태에서 동시 진행)
장점 : stop-the-world 시간이 매우 짧다. 모든 Application의 응답 속도가 매우 중요할때 CMS GC를 사용 단점 : 다른 GC 방식보다 메모리와 CPU를 많이 사용하며, compaction 단계가 기본적으로 제공되지 않음
OPEN
SNS Why & What Conclusion How &
Implement
G1 GC
G1 GC는 바둑판의 각 영역에 객체를 할당하고 GC를 실행 해당 영역이 차면 다른 영역으로 객체를 할당하고 GC를 실행 Young의 세가지 영역에서 데이터가 Old 영역으로 이동하는 단계가 사라진 GC 방식 G1 GC는 CMS GC를 대체하기 위해 만들어짐 G1 GC의 가장 큰 장점은 성능
4가지 GC방식보다 빠르지만 JDK 6에서는 G1 GC를 early access라고 부르며 JDK 7에서 정식으로 G1 GC를 포함하여 제공 JDK 6에서 G1 GC를 적용했다가 JVM Crash가 발생한 경우도 있음
OPEN
SNS Why & What Conclusion How &
Implement
GC 방식에 따라 지정 가능한 옵션
구 분 옵 션 설 명
Serial GC -XX:+UseSerialGC
Parallel GC -XX:+UseParallelGC -XX:ParallelGCThreads=value
Parallel Compaction GC
-XX:+UseParallelOldGC
CMS GC
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=value -XX:+UseCMSInitiatingOccupancyOnly
G1 -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC
JDK 6에서는 두 옵션을 반드시 같이 사용
OPEN
SNS Why & What Conclusion How &
Implement
GC 튜닝 절차
GC 모니터링
GC 튜닝 여부 결정
GC 방식/메모리 크기 지정
결과 분석
반영 및 종료
OPEN
SNS Why & What Conclusion How &
Implement
GC 튜닝 절차
GC 모니터링
GC 튜닝 여부 결정
GC 방식/메모리 크기 지정
결과 분석
반영 및 종료
JStat 명령어로 확인 1. YGC(Young Generation)의 GC이벤트 발생횟수와 YGCT(Young Generation의 GC 수행 누적 시간) 값을 확인 Minor GC 평균값 = YGCT / YGC
2. FGC(Full GC 이벤트가 발생한 횟수)와 GFCT(Full GC 수행 누적 시간) 값을 확인 Full GC 평균값 = FGCT / FGC
-verbosegc 옵션으로 로그를 남겨 분석
OPEN
SNS Why & What Conclusion How &
Implement
GC 튜닝 절차
GC 모니터링
GC 튜닝 여부 결정
GC 방식/메모리 크기 지정
결과 분석
반영 및 종료
해당 시스템이 가져야 할 목표와 비교 1. Minor GC 처리시간 (50ms 내외) 2. Minor GC 주기 (10초 내외) 3. Full GC의 처리시간 (1초 이내) 4. Full GC의 주기 (10분에 1회)
OPEN
SNS Why & What Conclusion How &
Implement
GC 튜닝 절차
GC 모니터링
GC 튜닝 여부 결정
GC 방식/메모리 크기 지정
결과 분석
반영 및 종료
1. GC 방식 Serial GC Parallel GC Parallel Old GC Concurrent Mark & Sweep GC G1(Garbage First) GC 2. 메모리 크기 메모리가 크면 GC 발생 횟수 감소 GC 수행 시간 증가 메모리가 작으면 GC 발생 횟수 증가 GC 수행 시간 감소
<af type="tenured" id="11" timestamp="Apr 07 17:30:12 2016" intervalms="8412.951"> <minimum requested_bytes="32" /> <time exclusiveaccessms="0.057" meanexclusiveaccessms="0.057" threads="0" lastthreadtid="0x3E609D00" /> <refs soft="85528" weak="84112" phantom="671" dynamicSoftReferenceThreshold="26" maxSoftReferenceThreshold="32" /> <tenured freebytes="10737152" totalbytes="536870912" percent="1" > <soa freebytes="0" totalbytes="526133760" percent="0" /> <loa freebytes="10737152" totalbytes="10737152" percent="100" /> </tenured> <gc type="global" id="11" totalid="11" intervalms="8416.676"> <classunloading classloaders="33" classes="0" timevmquiescems="0.000" timetakenms="1.443" /> <timesms mark="164.113" sweep="11.111" compact="0.000" total="176.810" /> <tenured freebytes="447416976" totalbytes="536870912" percent="83" > <soa freebytes="442048656" totalbytes="531502592" percent="83" /> <loa freebytes="5368320" totalbytes="5368320" percent="100" /> </tenured> </gc> <tenured freebytes="447415536" totalbytes="536870912" percent="83" > <soa freebytes="442047216" totalbytes="531502592" percent="83" /> <loa freebytes="5368320" totalbytes="5368320" percent="100" /> </tenured> <refs soft="85517" weak="2738" phantom="671" dynamicSoftReferenceThreshold="26" maxSoftReferenceThreshold="32" /> <time totalms="187.235" /> </af>
IBM JVM Garbage Collection
Large Object의 할당을 효과적으로 하기 위한 것 64KB 이상의 Object를 할당할 때 사용 Heap에서 할당이 불가능할 때도 사용 됨 Xloratio옵션으로 LOA를 위한 예약공간 지정 가능(0.5~0.95 까지 설정) Java 5에서는 –Xloainitial (default 0.05, 5%), -Xloamaximum(default 0.5, 50%) 설정 가능 이 옵션은 보통 1MB이상의 Object를 위한 목적으로 사용
Large Object Area
Large Object Area
-Xloainitial0.15 -Xloamaximum0.4
jdk 1.4 이상 -Xloratio : loa 영역의 크기를 백분률로 지정 loa 영역을 지정한 경우, 통상적으로 Xmx영역을 일정비율 조정
New Xmx = Current Xmx / (1 - loratio)
jdk 1.5이상 -Xloa : 64k 이상의 large object들만을 담는 loa(large object area)를 활성화 -Xloainitial : loa영역의 초기 백분률로 0~0.95의 수치를 지정, 기본값은 0.05(5%) -Xloamaximum : loa영역의 최대 백분률로 0~0.95의 수치를 지정, 기본값은 0.5(50%)
OPEN
SNS Why & What Conclusion How &
Implement
GC 튜닝 절차
GC 모니터링
GC 튜닝 여부 결정
GC 방식/메모리 크기 지정
결과 분석
반영 및 종료
다음 사항 확인 1. GC 수행 시간 Full GC 수행 시간 2. GC 수행 간격 3. GC 수행 횟수
<af type="tenured" id="59" timestamp="May 03 02:50:48 2016" intervalms="46173851.864"> <minimum requested_bytes="16" /> <time exclusiveaccessms="0.066" meanexclusiveaccessms="0.066" threads="0" lastthreadtid="0x33D1EF00" /> <refs soft="22725" weak="30660" phantom="3424" dynamicSoftReferenceThreshold="22" maxSoftReferenceThreshold="32" /> <tenured freebytes="1463728" totalbytes="196854272" percent="0" > <soa freebytes="0" totalbytes="195279872" percent="0" /> <loa freebytes="1463728" totalbytes="1574400" percent="92" /> </tenured> <gc type="global" id="68" totalid="68" intervalms="46173851.911"> <classunloading classloaders="0" classes="0" timevmquiescems="0.000" timetakenms="1.369" /> <contraction type="tenured" amount="1377280" newsize="195476992" timetaken="0.000" reason="excess free space following gc" /> <finalization objectsqueued="624" /> <timesms mark="167.672" sweep="1.974" compact="0.000" total="202.560" /> <tenured freebytes="137047688" totalbytes="195476992" percent="70" > <soa freebytes="135735336" totalbytes="194108928" percent="69" /> <loa freebytes="1312352" totalbytes="1368064" percent="95" /> </tenured> </gc> <tenured freebytes="137046936" totalbytes="195476992" percent="70" > <soa freebytes="135734584" totalbytes="194108928" percent="69" /> <loa freebytes="1312352" totalbytes="1368064" percent="95" /> </tenured> <refs soft="7336" weak="7506" phantom="3420" dynamicSoftReferenceThreshold="22" maxSoftReferenceThreshold="32" /> <time totalms="202.668" /> </af>
IBM JVM Garbage Collection
OPEN
SNS Why & What Conclusion How &
Implement
GC 튜닝 절차
GC 모니터링
GC 튜닝 여부 결정
GC 방식/메모리 크기 지정
결과 분석
반영 및 종료
결과에 만족한다면 해당 시스템 전체 서버 적용 JVM Bug, 잘못된 JVM 옵션으로 인하여 OutOfMemoryError와 같은 이상 현상 발생 지속적인 모니터링
OPEN
SNS Why & What Conclusion How &
Implement
JMap
Prints the memory map of a Java process
Command
jmap –heap JAVA_PID jmap –dump:file=/PATH/FileName.map JAVA_PID
OPEN
SNS Why & What Conclusion How &
Implement
JMap heap
$ jps or ps –ef | grep java $ jmap –heap JAVA_PID > jmap.out Attaching to process ID 3723, please wait... Debugger attached successfully. Server compiler detected. JVM version is 24.91-b01
OPEN
SNS Why & What Conclusion How &
Implement
JMap
jmap –heap using thread-local object allocation. Parallel GC with 2 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 536870912 (512.0MB) NewSize = 1310720 (1.25MB) MaxNewSize = 17592186044415 MB OldSize = 5439488 (5.1875MB) NewRatio = 2 SurvivorRatio = 8 PermSize = 21757952 (20.75MB) MaxPermSize = 174063616 (166.0MB) G1HeapRegionSize = 0 (0.0MB)
OPEN
SNS Why & What Conclusion How &
Implement
JMap dump jhat
$ jmap –dump:file=/PATH/FileName.map JAVA_PID
Dumping heap to /PATH/FileName.map ... Heap dump file created $ jhat /PATH/FileName.map or jhat –J-Xmx1024m /PATH/FileName.map
Reading from /PATH/FileName.map... Dump file created Sun Apr 24 12:22:35 UTC 2016 Snapshot read, resolving... Resolving 902275 objects... WARNING: Failed to resolve object id 0xd6dbc168 for field constantPoolOop (signature L) WARNING: Failed to resolve object id 0xd6dbc168 for field constantPoolOop (signature L) Chasing references, expect 180 dots.................................................................................. Eliminating duplicate references........................................................................................ Snapshot resolved. Started HTTP server on port 7000 Server is ready.
OPEN
SNS Why & What Conclusion How &
Implement
Basic Information
Tools Overview Installation Is It Free Include With JDK
nGrinder APM solution restart app with
agent yes no
JMap/JHat prints memory
map no yes yes
JVisualVM profiler no yes yes
JStack prints thread
dump no yes yes
Scouter APM solution restat app with
agent yes no
GC Memory
OPEN
SNS Why & What Conclusion How &
Implement
Data In Tool
Tools App
Response Time
DB Response
Time
Error Info
Thread Info
nGrinder Yes Yes Yes Yes Yes Yes
JMap/JHat Yes
JVisualVM Yes Yes Yes Yes
JStack Yes
Scouter Yes Yes Yes Yes Yes Yes
OPEN
SNS Why & What Conclusion How &
Implement
Errors
어플리케이션 에러
Application Response Time
요청에 대한 처리 시간
Database Response Time
요청에 대한 처리 시간
Thread State
Active thread states
Garbage Collection
GC 수행 시간
Memory Allocation
Heap and Perm Gen
Check Point
OPEN
SNS Why & What Conclusion How &
Implement
운다......왜?
OPEN
SNS Why & What Conclusion How &
Implement
Site 너무 느려요...
OPEN
SNS Why & What Conclusion How &
Implement
JVisualVm, JStack
Let’s Investigate!
OPEN
SNS Why & What Conclusion How &
Implement
JVisualVM
모두들 ... java 설치 위치 아시죠?
C:\Program Files (x86)\Java\jdk1.6.0_32\bin\JVisualVM.exe C:\Program Files (x86)\Java\jdk1.6.0_32\bin\JStack.exe
OPEN
SNS Why & What Conclusion How &
Implement
JVisualVM
OPEN
SNS Why & What Conclusion How &
Implement
JVisualVM
OPEN
SNS Why & What Conclusion How &
Implement
JVisualVM
GC Info
Memory Info
Thread Info
OPEN
SNS Why & What Conclusion How &
Implement
JVisualVM
< 원격지 서버 JVM의 command option 추가 > -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1403 (변경가능) -Dcom.sun.management.jmxremote.ssl=false (남들이 들어오는게 싫다면 true) -Dcom.sun.management.jmxremote.authenticate=false (남들이 들어오는게 싫다면 true)
OPEN
SNS Why & What Conclusion How &
Implement
JVisualVM – 이 thread 패널에서 무엇이 문제일까요?
OPEN
SNS Why & What Conclusion How &
Implement
JVisualVM
http 요청을 처리하는 일군들...
OPEN
SNS Why & What Conclusion How &
Implement
JVisualVM
OPEN
SNS Why & What Conclusion How &
Implement
* Provides the current stack trace for each thread in a local JVM (thread dump) - Windows : ctrl+break on windows - linux and macs : Command: kill -3 PID * 프로세스를 죽이지 않고 할 수 있는 방법은 ? - jstack -l JAVA_PID > /tmp/jstack.out
잠깐!! Command line Time!
OPEN
SNS Why & What Conclusion How &
Implement
JStack 결과
OPEN
SNS Why & What Conclusion How &
Implement
Do Not Block Threads!!
문제의 소스
Thread.sleep(10000);
OPEN
SNS Why & What Conclusion How &
Implement
Waiting for more requests to come in
수정 후 JStack
OPEN
SNS Why & What Conclusion How &
Implement
Basic Information
Tools Overview Installation Is It Free Include With JDK
nGrinder APM solution restart app with
agent yes no
JMap/JHat prints memory
map no yes yes
JVisualVM profiler no yes yes
JStack prints thread
dump no yes yes
Scouter APM solution restat app with
agent yes no
GC Memory
OPEN
SNS Why & What Conclusion How &
Implement
Data In Tool
Tools App
Response Time
DB Response
Time
Error Info
Thread Info
nGrinder Yes Yes Yes Yes Yes Yes
JMap/JHat Yes
JVisualVM Yes Yes Yes Yes
JStack Yes
Scouter Yes Yes Yes Yes Yes Yes
OPEN
SNS Why & What Conclusion How &
Implement
JVM
Class Loader
Execution Engine
Runtime Memory
Areas
• Loading • Linking • Initialization
<thread safe> • Stack • PC Register • Native Method Stack
• Interpreter • JIT Compiler • Profiler • Garbage Collector
Reminding JVM Architecture
Thread #1 Thread #2
Thread #3
Method Area (Runtime Constant
Pool) Heap
PC Register
Stack
Native Method Stack
Class Loader
Execution Engine Runtime Memory Area
OPEN
SNS Why & What Conclusion How &
Implement
Thread Area
이봐. 나 non thread safe 영역인
Method Area(code Area)에 있는 전역변수 좀 접근하자.
뭔소리래. 내가 먼저 주인한테 물어봐서
티켓(모니터) 받아서 사용중인데…
OPEN
SNS Why & What Conclusion How &
Implement
Thread and non Thread Safe Area
그럼 어쩌란 거니
내가 사용못하게 잠궈놨으니까(Object locking) 대기리스트(Object wait pool)에 이름올리고
대기해.
OPEN
SNS Why & What Conclusion How &
Implement
Thread and non Thread Safe Area
OPEN
SNS Why & What Conclusion How &
Implement
Thread Diagram
한 스레드가 락을 소유하고 있어 다른 스레드가 락을 획득하지 못해 애플리케이션의 전체적인 성능이 느려지는 경우
OPEN
SNS Why & What Conclusion How &
Implement
Thread 덤프 별 유형
"BLOCKED_TEST pool-1-thread-1" prio=6 tid=0x0000000006904800 nid=0x28f4 runnable [0x000000000785f000] java.lang.Thread.State: RUNNABLE at java.io.FileOutputStream.writeBytes(Native Method) at java.io.FileOutputStream.write(FileOutputStream.java:282) .........중략......... at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:44) - locked <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState) at com.nbp.theplatform.threaddump.ThreadBlockedState$1.run(ThreadBlockedState.java:17) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662)
Locked ownable synchronizers: -<0x0000000780a31758> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"BLOCKED_TEST pool-1-thread-2" prio=6 tid=0x0000000007673800 nid=0x260c waiting for monitor entry [0x0000000008abf000] java.lang.Thread.State: BLOCKED (on object monitor) at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:43) - waiting to lock <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState) at com.nbp.theplatform.threaddump.ThreadBlockedState$2.run(ThreadBlockedState.java:26) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662)
Locked ownable synchronizers: - <0x0000000780b0c6a0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
1. 락을 획득하지 못하는 경우(BLOCKED)
스레드 A가 작업을 계속하려면 스레드 B가 소유한 락을 획득해야 하고, 스레드 B가 작업을 계속하려면 스레드 A가 소유한 락을 획득해야 해서 데드락 상태에 있는 경우
OPEN
SNS Why & What Conclusion How &
Implement
Thread 덤프 별 유형
2. 데드락 상태인 경우
"DEADLOCK_TEST-1" daemon prio=6 tid=0x000000000690f800 nid=0x1820 waiting for monitor entry [0x000000000805f000] java.lang.Thread.State: BLOCKED (on object monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197) - waiting to lock <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182) - locked <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
Locked ownable synchronizers: -None
"DEADLOCK_TEST-2" daemon prio=6 tid=0x0000000006858800 nid=0x17b8 waiting for monitor entry [0x000000000815f000] java.lang.Thread.State: BLOCKED (on object monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197) - waiting to lock <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182) - locked <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
Locked ownable synchronizers: -None
"DEADLOCK_TEST-3" daemon prio=6 tid=0x0000000006859000 nid=0x25dc waiting for monitor entry [0x000000000825f000] java.lang.Thread.State: BLOCKED (on object monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197) - waiting to lock <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182) - locked <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
Locked ownable synchronizers: - None
OPEN
SNS Why & What Conclusion How &
Implement
Thread 덤프 별 유형
3. 원격 서버로부터 메시지 수신을 받기 위해 계속 대기하는 경우
정상적인 Runnable상태이나 무한정 대기
“socketReadThread" prio=6 tid=0x0000000006a0d800 nid=0x1b40 runnable [0x00000000089ef000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:129) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158) - locked <0x00000007d78a2230> (a java.io.InputStreamReader) at sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:107) - locked <0x00000007d78a2230> (a java.io.InputStreamReader) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:93) at java.io.InputStreamReader.read(InputStreamReader.java:151) at com.nbp.theplatform.threaddump.ThreadSocketReadState$1.run(ThreadSocketReadState.java:27) at java.lang.Thread.run(Thread.java:662)
OPEN
SNS Why & What Conclusion How &
Implement
Thread 덤프 별 유형
4. 스레드 리소스를 정상적으로 정리하지 못하는 경우
불필요한 스레드가 계속해서 늘어나는 경우 -> 쓰레드 종료조건 확인 필요
Step B : What processes are using cpu?
OPEN
SNS Why & What Conclusion How &
Implement
TIPs for GOAL
Step C (part 1) : Identifying the suspect threads Finding Java threads
Step C (part 2) : Threaddumps
Step A : Do we have high cpu?
OPEN
SNS Why & What Conclusion How &
Implement
또 운다......대체 왜?
OPEN
SNS Why & What Conclusion How &
Implement
Site is not accessible
도대체가… 접속이 안되는데 어떻게 하라는 건가요
OPEN
SNS Why & What Conclusion How &
Implement
JVisualVM(with mBean)
Let’s Investigate!
OPEN
SNS Why & What Conclusion How &
Implement
Mbean Plugin Installation
OPEN
SNS Why & What Conclusion How &
Implement
Check Busy Thread Count and Max Thread Count
200
OPEN
SNS Why & What Conclusion How &
Implement
Max Threads Count 늘리기
각 WAS 마다 설정 파일 및 설정 방법은 다름 - Websphere의 경우 각 JVM마다 server.xml 에서 WebContainer, ORB/RMI thread count설정 가능 - Jeus의 경우 각 JVM마다 WebContainer는 WebMain.xml에 ORB/RMI thread count는 EJBMain.xml
- Tomcat의 경우 server.xml에서 설정 가능 Ex ) <connector connectiontimeout="20000" maxthreads="400" port="8080" protocol="HTTP/1.1" redirectport="8443" />
• Performance Test Tool
• What Is JVM GC Memory Allocation Thread State
• Simple Tunning Point
• Performance Test Tool
• What Is JVM GC Memory Allocation Thread State
• Simple Tunning Point
• nGrinder • JMap/JHat • JVisualVM • JStack • Scouter
• Performance Test Tool
• What Is JVM GC Memory Allocation Thread State
• Simple Tunning Point
• ClassLoader (로딩,링킹,초기화)
• Runtime Memory Areas • Execution Engine
• Performance Test Tool
• What Is JVM GC Memory Allocation Thread State
• Simple Tunning Point
• Serial GC • Parallel GC • CMS GC • G1 GC
• Performance Test Tool
• What Is JVM GC Memory Allocation Thread State
• Simple Tunning Point
• Stack, PC Register, Native • Heap Area • Method Area
• Performance Test Tool
• What Is JVM GC Memory Allocation Thread State
• Simple Tunning Point
• non Thread Safe • runnable, blocked • cpu 점유률 , 수행시간 • Current Thread Busy count
• Performance Test Tool
• What Is JVM GC Memory Allocation Thread State
• Simple Tunning Point
Memory든 GC 든 Thread던 무조건 D u m p 를 떠라. Dump안에 모든게 있을 지니.
누구의 역할 ?
6개월
11개월