홈 › 리눅스 운영 › 09 / 13

장애 대응 (jstack·jmap·OOM killer·FD)

섹션 7진행 0 / 13

3. 코드 예제

예제 1: 스레드 덤프 읽기 — 01_incident.sh 발췌

bash
jstack "$PID" > td1.txt
grep -c '^"' td1.txt
grep -A2 '"busy-worker"' td1.txt | head -n 3
grep -A2 '"lock-waiter"' td1.txt | head -n 3
grep -E '^\s+- (waiting to lock|locked)' td1.txt | sort | uniq -c
text
스레드 수: 21
"busy-worker" #21 daemon prio=5 cpu=4484.38ms elapsed=6.59s nid=38040 runnable
   java.lang.Thread.State: RUNNABLE
	at Incident.lambda$main$0(Incident.java:12)
"lock-waiter" #23 daemon prio=5 cpu=0.00ms elapsed=6.38s nid=43052 waiting for monitor entry
   java.lang.Thread.State: BLOCKED (on object monitor)
	at Incident.lambda$main$2(Incident.java:23)
      1 	- locked <0x00000000ffc57c30> (a java.lang.Object)
      1 	- waiting to lock <0x00000000ffc57c30> (a java.lang.Object)

cpu=4484ms 가 6.6초 동안 4.5초를 썼다는 뜻이라 CPU 범인이 바로 보입니다. Incident.java:12 가 그 코드 줄입니다. 같은 주소를 잡은 쪽과 기다리는 쪽이 잠금 관계입니다.

예제 2: 상태별 집계 — 01_incident.sh 발췌

bash
grep -oE 'java.lang.Thread.State: [A-Z_]+' td1.txt | sort | uniq -c | sort -rn
text
      9 java.lang.Thread.State: RUNNABLE
      3 java.lang.Thread.State: TIMED_WAITING
      1 java.lang.Thread.State: WAITING
      1 java.lang.Thread.State: BLOCKED

02 레슨의 빈도 패턴을 덤프에 적용한 것입니다. 운영 서버에서 BLOCKED 가 두 자리면 잠금, RUNNABLE 이 스레드 풀 크기와 같으면 풀 고갈입니다.

예제 3: 힙 상태와 히스토그램 — 01_incident.sh 발췌

bash
jcmd "$PID" GC.heap_info | head -n 3
jstat -gcutil "$PID" 1000 2 | tail -n 2
jmap -histo:live "$PID" | head -n 6
text
 garbage-first heap   total 260096K, used 105390K
  region size 1024K, 3 young (3072K), 0 survivors (0K)
     -      -   8.70  43.29  53.07  10.80      0     0.000     0     0.000
 num     #instances         #bytes  class name (module)
   1:          2829       52588720  [B ([email protected])
   2:           138         160824  [C ([email protected])

[B 가 52MB 로 1위이고 데모 앱이 byte[1MB] 50개를 리스트에 넣은 것과 맞습니다. 실제 앱에서는 이 자리에 누수 클래스가 옵니다.

예제 4: 힙 덤프 파일 — 01_incident.sh 발췌

bash
jcmd "$PID" GC.heap_dump "$WORK/heap.hprof"
ls -l "$WORK/heap.hprof"
text
Heap dump file created [55721329 bytes in 0.103 secs]
55721329 bytes

힙 사용량 105MB 중 살아 있는 객체만 55MB 로 기록됐습니다. 운영 힙 4GB 면 파일도 수 GB 이므로 디스크 여유를 먼저 확인합니다.