스레드덤프 (thread dump)

2021. 3. 21. 02:02 JAVA/Java

참조문서 : https://d2.naver.com/helloworld/10963

관련 포스팅 : http://sjh836.tistory.com/121

1. 들어가며

1-1. 스레드의 종류

  • Daemon Thread
    • 작업을 돕는 보조적인 역할을 수행하는 쓰레드 (GC 도 여기에 해당)
    • 프로세스 종료시 데몬 쓰레드는 강제적으로 자동종료
    • 언제든지 종료가 되어도 상관없는 작업 시에 사용 (그래서 주로 데몬쓰레드를 쓴다)
    • Thread t = new Thread(); t.setDaemon(true); 로 설정가능
  • Non-Daemon Thread
    • 실제 주 작업을 하는 스레드
    • 프로세스 종료시 논데몬 쓰레드가 살아있는 경우 종료 불가능 (가끔 톰캣을 종료했지만 안꺼져서 kill 해야되는 이유)
    • 매우 중요한 데이터 처리시에 사용하는 것이 일반적

1-2. 스레드덤프를 추출해보면 좋은 상황

  1. 모든 시스템에 응답이 없을 때
  2. 사용자 수가 많지 않은데 CPU사용량이 높을때
  3. 특정어플리케이션 수행 시 응답이 없을때
  4. 간헐적으로 응답이 느릴때
  5. 서비스 실행시간이 길어질수록 응답시간이나 cpu 사용량이 늘어날떄 등등

1-3. 멀티스레드 프로그래밍을 안하는데?

java.lang.Thread 를 이용해서 직접 개발하지 않더라도 이미 프레임워크, WAS, 라이브러리에서 내부적으로 사용하고 있다.

만약 라이브러리에서 문제가 생긴다면?? 이럴때 스레드덤프를 쓸 줄 안다면 유용할 것이여~~

2. 스레드덤프 생성하기

  • OS단에서
    • 리눅스 : kill -3 [PID]
    • 윈도우 : Ctrl + Break
  • java단에서 (jps -v 로 java 프로세스 확인)
    • jstack [PID] (jstack으로 반응이 없는 경우 –F 옵션)
    • jcmd [PID] Thread.print (jdk7 이후 등장)
      • jcmd [PID] help 로 명령어 확인 가능, 직관적임
  • 이때 시간이 있다면 텀을 두고 3~4장을 떠두는게 좋다.

3. 스레드덤프를 읽어보자

  • 스레드이름
    • lang.Thread 클래스로 생성하면 'Thread-숫자' 형식으로 생성된다.
    • DefaultThreadFactory 를 사용하면 pool-숫자-thread-숫자 형식으로 생성된다.
    • 하지만 이런 디폴트이름들로 쓰레드가 가득하다면 덤프를 읽기가 매우 힘들다. 멀티스레드 프로그래밍을 직접할 경우, setName을 이용해서 직관적인 스레드명을 써주는게 좋다.
  • 우선순위 : 스레드 우선순위 (스펙에서도 안중요하다고 함)
  • 스레드 아이디
    • 16진수
    • tid : 자바레벨 쓰레드ID, 자바프로세스마다 1부터 시작. 겹칠수 있겠다.
      • ThreadMXBean과 ThreadInfo 을 이용하여 정보 획득 가능
    • nid : 네이티브 쓰레드ID, OS영역이고 유니크함
      • ps 명령어를 이용해 cpu 사용율 등도 알 수 있음
  • 스레드 상태
    • runnable
    • blocked
      • deadlock
    • wait
  • 스레드 콜스택

4. 스레드덤프의 각종 도구

4-1. JVisualVM

jdk 설치할 때 같이 설치되므로, 환경변수가 잘 잡혀있다면 jvisualvm 이라고 치면 바로 뜬다.

4-2. TDA

  • Thread Dump Analyzer
  • 오래되고 jvm 별로 포맷이 달라 안읽히는 경우도 있음

4-3. fastThread 사이트

fastthread.io



출처: https://sjh836.tistory.com/151?category=679845 [빨간색코딩]