Thread Dump - Growth-of-server-developer/Java GitHub Wiki

동기

  • μ‚¬λ‚΄μ—μ„œ μ‚¬μš©ν•˜λŠ” Confluence μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ κ°‘μž‘μŠ€λŸ° λ‹€μš΄
  • 사내 μ˜μ—…μ •λ³΄ μ‹œμŠ€ν…œ μ„±λŠ₯ μ €ν•˜ 이슈

μŠ€λ ˆλ“œ 덀프λ₯Ό ν•œ 번만 νšλ“ν•˜λ©΄ 될 쀄 μ•Œμ•˜λŠ”λ° μŠ€λ ˆλ“œ μƒνƒœ λ³€ν™”λ₯Ό ν™•μΈν•˜κΈ° μœ„ν•΄ 5초 μ •λ„μ˜ κ°„κ²©μœΌλ‘œ μ—¬λŸ¬ 번(5~10회) νšλ“ν•˜λŠ” 것이 μ’‹λ‹€κ³  ν•œλ‹€. ν•„μžλŠ” μŠ€λ ˆλ“œ 덀프 ν•œ 번 νšλ“ ν›„, μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μž¬κΈ°λ™μ„ ν–ˆλ‹€...λͺ…μ‹¬ν•˜λ„λ‘ ν•˜μž.

ν•„μžλŠ” jstack을 μ΄μš©ν•˜μ—¬ μŠ€λ ˆλ“œ 덀프λ₯Ό νšλ“ν–ˆλŠ”λ° λ¦¬λ”λ‹˜κ»˜μ„œ kill도 κ°€λŠ₯ν•˜λ‹€κ³  λ§μ”€ν•˜μ…¨λ‹€. κ·Έλž˜μ„œ ν•΄λ‹Ή 방법을 μ •λ¦¬ν•˜μ˜€λ‹€.

  1. jstack μ‚¬μš© λ¨Όμ € OS λ‚΄μ—μ„œ μ‹€ν–‰ 쀑인 Java μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ν”„λ‘œμ„ΈμŠ€λ₯Ό ν™•μΈν•œλ‹€.
jps -v

ν•„μžλŠ” Confluence ν”„λ‘œμ„ΈμŠ€λ§Œ ν™•μΈν•˜λ©΄ 됐기에 λ‹€μŒκ³Ό 같이 μž…λ ₯ν•˜μ˜€λ‹€.

jps -v | grep confluence

이λ₯Ό 톡해 ν”„λ‘œμ„ΈμŠ€ IDλ₯Ό ν™•μΈν•˜κ³  jstack 인수둜 PID(ν”„λ‘œμ„ΈμŠ€ ID)λ₯Ό λ„£μ–΄ μŠ€λ ˆλ“œ 덀프λ₯Ό νšλ“ν•œλ‹€. PIDκ°€ 10975라면 μ•„λž˜μ™€ 같이 μž…λ ₯ν•œλ‹€.

jstack 10975

μ—¬κΈ°μ„œ μ£Όμ˜ν•  점은 "thread dumpκ°€ 어디에 μƒμ„±λ˜λŠ”κ°€?" 이닀. μœ„ λͺ…λ Ήμ–΄λ§Œ μž…λ ₯ν–ˆμ„ 경우 STDOUT(ν‘œμ€€ 좜λ ₯)으둜 좜λ ₯λœλ‹€. 그렇기에 λͺ…λ Ήμ–΄λ§Œ μž…λ ₯ν•œλ‹€κ³  ν˜„μž¬ κ²½λ‘œμ— λ–‘ν•˜λ‹ˆ μŠ€λ ˆλ“œ 덀프가 μƒμ„±λ˜λŠ”κ±΄ μ•„λ‹ˆλ‹€. ν•„μžμ˜ 경우 WAS(Web Application Server)이기에 둜그 파일(catlina.out)에 λ‚¨κ²Œ λœλ‹€.

λ”°λΌμ„œ 이λ₯Ό 둜그 파일둜 κ΄€λ¦¬ν•˜κ³ μž ν•  λ•ŒλŠ” λ‹€μŒκ³Ό 같이 μž…λ ₯ν•œλ‹€.

jstack 10975 > thread_dump_20200730.log
  1. kill μ‚¬μš© μœ„ 방법 κ·ΈλŒ€λ‘œ PIDλ₯Ό ν™•μΈν•œλ‹€. (μ—¬κΈ°μ„  jps 말고 ps λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜μ˜€λ‹€. ps λͺ…λ Ήμ–΄κ°€ μ˜΅μ…˜μ„ λͺ¨λ‘ λ³΄μ—¬μ£ΌλŠ” 것 κ°™λ‹€.)
ps -ef | grep confluence

PIDκ°€ 10975라면 μ•„λž˜μ™€ 같이 μž…λ ₯ν•œλ‹€.

kill -3 10975

μ—¬κΈ°μ„œ μ˜΅μ…˜ -3μ—μ„œ 3은 SIGQUITμ΄λ‚˜ SIGOUT으둜 "kill -l"을 톡해 확인할 수 μžˆλ‹€. λ¬Όλ‘  이 λͺ…령어도 STDOUT으둜 좜λ ₯λ˜μ–΄ (ν•„μžμ˜ 경우) 둜그 νŒŒμΌμ— λ‚¨κ²Œλœλ‹€.

μ΄λ ‡κ²Œ νšλ“ν•œ μŠ€λ ˆλ“œ 덀프λ₯Ό 보게되면...특히 처음 보게 λœλ‹€λ©΄ 겁먹지 말자. 데이터λ₯Ό μ½λŠ” λ°©λ²•λ§Œ μ•Œλ©΄ μ–΄λ ΅μ§€ μ•Šλ‹€.

2020-07-23 12:54:00
Full thread dump OpenJDK 64-Bit Server VM (25.181-b13 mixed mode):

"Attach Listener" #10081 daemon prio=9 os_prio=0 tid=0x00007fff842a4800 nid=0x163ad waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"Structure-Jobs6087270f Queue-Thread#1170" #10080 daemon prio=5 os_prio=0 tid=0x00007fff28153000 nid=0x162e0 waiting on condition [0x00007ffe7c0d1000]
   java.lang.Thread.State: TIMED_WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000006d362b858> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
	at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
	at com.almworks.structure.commons.job.PooledStructureJobManager$JobThread.run(PooledStructureJobManager.java:502)

   Locked ownable synchronizers:
	- None

"mondrian.rolap.agg.SegmentCacheManager$sqlExecutor_14" #9642 daemon prio=5 os_prio=0 tid=0x00007fff0c3a8800 nid=0x9d1a waiting on condition [0x00007ffe7b8cb000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000006fa7fe0e8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
	- None
"pool-84-thread-1" #1869 prio=5 os_prio=0 tid=0x00007ffed067e800 nid=0x313ea runnable [0x00007ffe8accc000]
   java.lang.Thread.State: RUNNABLE
	at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
	at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
	at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
	at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
	- locked <0x0000000707e84b10> (a sun.nio.ch.Util$3)
	- locked <0x0000000707e84b00> (a java.util.Collections$UnmodifiableSet)
	- locked <0x0000000707e84918> (a sun.nio.ch.EPollSelectorImpl)
	at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(Unknown Source)
	at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(Unknown Source)
	at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
	- None

"Thread-805" #1868 daemon prio=5 os_prio=0 tid=0x00007ffed065c800 nid=0x313e9 in Object.wait() [0x00007ffe96e3b000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	at com.c.a.a.d.e.run(Unknown Source)
	- locked <0x0000000707e82620> (a com.c.a.a.d.e)

   Locked ownable synchronizers:
	- None

"JRubyWorker-8" #1519 daemon prio=5 os_prio=0 tid=0x00007fff5004a000 nid=0x16c3 waiting on condition [0x00007ffe8ccce000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000006edf6eb10> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
	at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
	- None
  • μ½λŠ” 법
  • μŠ€λ ˆλ“œ μƒνƒœ
  • 락

μ°Έκ³ 0