1. 명령어를 통해 프로세스의 thread 단위로 CPU 사용율을 모니터링하여 CPU를 많이 차지하는 thread 확인
prstat -L -m -p [프로세스ID] [Interval]
가장 높은 cpu를 차지하는 thread의 lwpid를 16진수로 변환 (= thread Dump의 nid)
ex) lwpid: 148 == nid: 0X94
또는 아래 명령어 사용 가능
ps -mo pid,lwp,stime,time,cpu -C java
가장 높은 cpu를 차지하는 thread의 TID를 16진수로 변환 (= thread Dump의 native ID)
그럼 해당 thread가 어떠한 작업을 수행중이며 왜 CPU를 많이 차지하는지 분석 가능!
2-1. Thread Dump 생성
sudo ps -aux | grep java 등과 같은 명령어로 pid 확인
– jcmd 이용
cd /원하는 폴더 jcmd $ Thread.print > $.print
– kill -3 이용
kill -3 pid
– visualVM 이용
visualVM –> 서버 연결 –> Threads –> Thread Dump 버튼 클릭
2-2. Heap Dump 생성
cd /원하는 폴더 jmap -dump:live,format=b,file=$.hprof $
3. Thread Dump 분석하기 위한 기초 지식
스레드 풀에서 요청이 처리되는 방법
웹 서버에서 .NET Framework는 ASP.NET 요청을 처리하는 데 사용되는 스레드 풀을 유지 관리함. 요청이 도착하면 해당 요청을 처리하기 위해 풀에서 하나의 스레드가 디스패치 됨. 요청이 동기적으로 처리되는 경우, 요청이 처리되는 동안 이 요청을 처리하는 스레드는 차단되며 다른 요청을 처리할 수 없다.
다수의 차단된 스레드를 수용할 수 있을 정도로 스레드 풀을 크게 만든다면 이는 문제가 되지 않을 수도 있으나 스레드 풀의 스레드 수는 제한되어 있다. 동시에 여러 개의 장기 실행 요청을 처리하는 대규모 응용 프로그램에서는 사용 가능한 모든 스레드가 차단될 수 있다. 이러한 상황을 스레드 고갈함. 이 상황에 이르면 웹 서버는 요청을 큐에 대기시키게 된다. 요청 큐가 꽉 차면 웹 서버는 HTTP 503 상태(서버 사용량이 많습니다.)를 통해 요청을 거부 한다.
thread status
- NEW: The thread is created but has not been processed yet.
- RUNNABLE: The thread is occupying the CPU and processing a task. (It may be in WAITINGstatus due to the OS’s resource distribution.)
- BLOCKED: The thread is waiting for a different thread to release its lock in order to get the monitor lock.
- WAITING: The thread is waiting by using a wait, join or park method.
- TIMED_WAITING: The thread is waiting by using a sleep, wait, join or park method. (The difference from WAITING is that the maximum waiting time is specified by the method parameter, and WAITING can be relieved by time as well as external changes.)
4. 분석 툴 사용
– ThreadLogic.jar 이용
과거 오라클 사이트에 있었으나 개편되면서 사라짐, 아래 링크로 개발자가 옮겨둠
https://github.com/sparameswaran/threadlogic
jar 파일 실행 –> File –> Open 선택 후, dump 파일을 열면 아래와 같은 화면이 나옴
각 thread 의 lock 상황과 어떤 thread 의 lock을 기다리고 있는지 확인 가능.
38번 thread 가 <0x00000000c53d4798> lock을 기다리고 있음
41번 thread 는 <0x00000000c53d4798> lock을 가지고 있음, 계속 되는 dump에서도 lock 을 가지고 있고 해당 lock 을 기다리는 thread가 증가함.
date를 가져오는 로직을 수행하면서 lock이 걸렸고 해당 부분으로 인해 다른 thread가 해결되지 않고 과도하게 생성되어 쌓이고 있는 것으로 보임
–> simpleDate 로직 확인 후, 수정 필요
전체적인 요약 정보는 아래 메뉴를 통해 확인 가능
DeadLock은 존재하지 않지만, 스레드가 너무 많거나 다른 이슈 존재함을 확인 가능
– visualVM
누구나 알듯이 java 설치 폴더 bin에 존재
– IBM HeapAnalyzer
– GCEASY 이용
메모리, 스레드 덤프 모두 확인 가능
개인적으로 추천!!!! 강추!!! 웹서버에서 파일을 넣으면 됨
그러면 아래와 같이 어떤 함수를 많이 사용하고 stacktrace 등 분석 내용이 많음