Core dump
- 리눅스에서 gcore라는 명령어를 사용해서 코어 덤프를 남길 수 있다.
- JVM은 hs_err_pid.log라는 파일을 남기고 죽는다.
- java에서 1GB의 메모리를 사용하면 코어 덤프는 수십기가에 달하는 파일을 생성한다.
- 아무 근거 없이 죽었다면 kill -9 <pid>로 죽었거나 segfault와 같이 프로세스 내의 오류로 죽은 경우
--> /var/log messages 로그를 봐야한다.
- JVM에서 Thread Dump는 현재 수행중인 쓰레드에 대한 호출 경로 StackTrace를 보기 위한 것이고 Heap Dump는 현재 Heap에서 점유되고 있는 객체들에 대한 조사를 위하여 필요한 내역
1. 코어덤프 자동으로 생성하게 만들기
- ulimit -a 명령어로 서버 설정을 확인한다.
- core file size (blocks, -c) 0 <-- 이처름 0이면 core dump는 안남는다.
- ulimit -c unlimited <-- core dump를 남기도록 변경
2. Core dump 분석하기
- gdb 프로그램 사용하면
- gdb / 자바실행파일 Full path /java core.pid <-- 실행
- 인터프리터 방식으로 이 툴을 사용할 수 있다.
3. 명령어
- bt
- info thread
- thread 쓰레드번호
- where
- x/i 메모리 주소값
[Thread dump]
4. 기타
- jstack / 자바실행파일 fullpath/java core.pid <-- core dump에서 쓰레드 덤프를 추출해준다.
- jmap <-- core dump에서 힙 덤프를 만들 수 있다.
5. Thread dump
- 명령: kill - 3 <pid>
- <pid>: jvm의 process Id
6. JVM 스레드 덤프 가져오는 방법
- 스레드 덤프를 2개 이상 가져오는 것이 좋다.
- 정기적으로 10개의 스레드 덤프를 가져오는 것이 좋다.
6-1 1단계 JAVA 프로세스에서 PID가져오기
- jps -l 70660 sun.tools.jps.Jps 70305
- Linux및 Unix에서 이 명령을 sudo -u user jps -l로 실행해야 할 수 있습니다. 여기서 user는 java 프로세스에서 실행중인 사용자의 사용자 이름임
- ps -el |grep java
6-2 JVM에서 스레드 덤프 요청
- jstack -l <pid>
- 콘솔 출력 리디렉션을 사용하여 파일로 연속 스레드 덤프를 출력하거나 지시문을 첨부할 수 있음
--> jstack -l <pic> >> threaddumps.log
--> sudo -u <java-user> jstack -l <pid>
- Xrs jvm 매개 변수가 활성화되어 있어도 jstack이 작동함
- sudo -u <java-user> jstack -l <pid>
6. 스레드 덤프로 확인할 수 있는 상황
- 모든 시스템에 응답이 없을 때
- 사용자 수가 많지 않은데 cpu 사용량이 높을 때
- 특정 어플리케이션 수행 시 응답이 없을 때
- 서비스 실행시간이 길어질 수록 응답시간이나 CPU 사용량이 늘어날 때 등등
- java.lang.Thread를 이용해서 직접개발하지 않았는데 이미 프레임워크, WAS, 라이브러리 내부적으로 사용하고 있을 때 내부적으로 문제가 생긴다면?
7. Thread의 종류
7-1. Deamon Thread
- 작업을 돕는 보조적인 역할을 수행하는 쓰레드(GC도 여기에 해당)
- 프로세스 종료 시 데몬 스레드는 강제적으로 자동 종료
- 언제든지 종료가 되어도 상관없는 작업 시에 사용(그래서 주로 데몬쓰레드를 쓴다.)
- Thread t = new Thread(); t.setDaemon(thue); 로 설정가능
7-2. Non-Daemon Thread
- 실제 주 작업을 하는 스레드
- 프로세스 종료 시 논 데몬 쓰레드가 살아있는 경우 종료 불가능(가끔 톰캣을 종료했지만 안꺼져서 kill 해야되는 이유)
- 매우 중요 데이터 처리시에 사용하는 것이 일반적
8. Thread 읽기
-
- 스레드 이름
- lang.Thread 클래스로 생성하면 'Thread-숫자' 형식으로 생성됨
- DefaultThreadFactory를 사용하면 pool-숫자-thread-숫자 형식으로 생성된다.
- 하지만 이런 디폴트 이름들로 쓰레드가 가득하다면 덤프를 읽기가 매우 힘들다. 멀티 스레드 프로그래밍을 직접할 경우 setName을 이용해서 직관적인 스레드명을 써주는게 좋다.
- 우선순위: 스레드 우선순위(스펙에서도 안중요하다고 함)
- 스레드 아이디
- 16진수
- tid: 자바레벨 쓰레드ID, 자바프로세스마다 1부터 시작. 겹칠 수 있겠다.
- nid: 네이티브 쓰레드 ID, OS영역이고 유니크함
- ps 명령어를 이용해 CPU사용율 등도 알 수 있음
- 스레드 상태
- runnable
- blocked
- deadlock
- wait
- 스레드 콜스택
9. 스레드 덤프의 각종 도구
- JVisualVM
-jdk 설치할 때 같이 설치되므로, 환경변수가 잘 잡혀있다면 jvisualvm이라고 치면 바로 뜬다.
- TDA
- Thread Dump Analyzer
- 오래되고 jvm 별로 포맷이 달라 안읽히는 경우도 있음
- fastThread 사이트
- fastthread.io
[heap dump]
10. heap
- JVM GC 블로깅에서 Old 영역을 많이 사용할 경우 일반적으로 사용되지 않는 객체들이 Reference되어 GC되지 않고 남아 있을 가능성이 높다. 이때는 어떤 객체들이 많이 점유되고 있는지 조사할 필요가 있다.
- Old 영역을 많이 점유하고 있으면 Full GC가 자주 오래동안 발생할 수 있으므로 업무 응답시간에 문제 또는 장애를 일으킬 소지가 있다.
- JDK6 명령: jmap -dump:format=b, file=<fileName> <PID>
- jmap은 JDK_HOME/bin에 포함되어있음
11. Heap Dump의 분석
- Eclipse Memory Analyzer Tool(mat) 을 이용한다.
- 독립 프로그램 다운로드: Heap Dump Size는 몇 Gbytes씩 되므로 64bit OS에서 64bit mat를 다운로드 받는다.
- memoryAnalyzerTool.ini파일의 초기값 설정을
+ ex) -Xms2048m -Xmx8192m (heap Dump file size 6Gbytes 일때)
-XX; MaxPerm Size=256m
-Xms40m
-Xm x512m
- mat에서 Heap Dump 파일을 로딩한다. 이 때 파일 확장자는 .hprof여야 한다. 6Gbytes로딩에 대략 수시간이 소요되니 인내심이 필요하다.
- mat통하여 Heap Dump 분석할 때 로컬 메모리가 부족할 경우 Swap Size를 확장하여 준다.
'Tech > Software' 카테고리의 다른 글
스위치 구분(L2, L3, L4, L7) (0) | 2019.09.03 |
---|---|
Google Cloud Essential Workshop (0) | 2019.09.03 |
EJB, JTA, XA, JMS (0) | 2019.03.09 |
sorting algorithm (0) | 2018.12.13 |
HTTP Status Code List (0) | 2018.12.13 |