힙은 남았는데 서비스가 멈췄다 · 스레드 덤프로 멈춘 이유를 찾는다 · 퀴즈
퀴즈: 스레드 덤프 읽기
문항 6개. 정답과 해설은 풀어 본 뒤에 보여 드립니다.
덤프에서 요청 스레드 150개가 `BLOCKED (on object monitor)` 이고 전부 같은 `waiting to lock <0x…>` 주소다. 원인을 찾는 다음 행동은?
- BLOCKED 스레드 150개의 스택을 하나씩 읽는다
- 같은 주소를 `- locked <0x…>` 로 쥔 스레드를 찾아 그 스택 맨 위를 본다
- 힙 덤프를 떠서 그 주소의 객체를 찾는다
- GC 로그에서 그 시각의 정지를 찾는다
jcmd 문서가 Thread.print 의 -l 옵션에 대해 적은 것은?
- 잠금을 쥔 스레드를 강제로 깨워 진행시킨다
- 덤프를 파일로 저장하고 화면에는 찍지 않는다
- java.util.concurrent 잠금 정보를 함께 찍는다
- RUNNABLE 상태의 스레드만 골라 찍는다
synchronized 대신 ReentrantLock 을 쓰는 코드의 덤프에서 기다리는 스레드는 어떻게 보이는가?
- BLOCKED 상태에 `waiting to lock`
- RUNNABLE 상태에 잠금 정보 없음
- TIMED_WAITING (sleeping) 에 Thread.sleep
- WAITING (parking) 에 `parking to wait for <…> (a …ReentrantLock$NonfairSync)`
ReentrantLock.tryLock(500, MILLISECONDS) 가 무한 대기 문제를 바꾸는 방식은?
- 잠금을 500ms 마다 강제로 뺏어 온다
- 500ms 안에 못 잡으면 false 를 돌려줘 요청을 빨리 실패시킬 수 있다
- 잠금을 쥔 스레드를 500ms 뒤 인터럽트한다
- 대기 스레드를 500개까지만 받는다
덤프를 몇 초 간격으로 세 장 찍으라고 하는 이유는?
- 한 장은 JVM 이 완전히 기록하지 못하기 때문이다
- 세 장을 합쳐야 모든 스레드가 나오기 때문이다
- 같은 스레드가 같은 자리에 계속 있어야 정말 멈춘 것이고, 매번 다르면 그냥 바쁜 것이기 때문이다
- 첫 장은 항상 안전 지점 대기 때문에 비어 있기 때문이다
서비스가 멈춘 것을 발견했을 때 이 코스가 말리는 첫 행동은?
- 재시작 — 덤프를 찍기 전에 증거가 사라진다
- jcmd -l 로 pid 확인
- curl 로 /health 확인
- 덤프 세 장 찍기