Java-2010410-debug 卡住的 java 進程

Intro

執行 java -jar xxx.jar時,出現了 java 進程卡住,屏幕上沒有任何輸出。

Debug 過程

查看系統日誌

查看 /var/log/syslog、/var/log/messages,都沒有報錯信息。

查看 Java 進程自己的輸出日誌

沒有報錯。

查看系統級別信息

# 查看進程
ps -ef |grep java

# 查看系統負載,沒有消耗過多資源
top

# 查看內存使用情況
free -mh

# 查看端口占據,沒有出現端口被佔的情況
ss -anp |grep 9600

查看 Java pid 對應的 /proc/[pid]/ 目錄內容

以下參考鏈接:Java程序卡住問題的解決
/proc/pid/cmdline 進程啓動命令
/proc/pid/cwd 鏈接到進程當前工作目錄
/proc/pid/environ 進程環境變量列表
/proc/pid/exe 鏈接到進程的執行命令文件
/proc/pid/fd 包含進程相關的所有的文件描述符
/proc/pid/maps 與進程相關的內存映射信息
/proc/pid/mem 指代進程持有的內存,不可讀
/proc/pid/root 鏈接到進程的根目錄
/proc/pid/stat 進程的狀態
/proc/pid/statm 進程使用的內存的狀態
/proc/pid/status 進程狀態信息,比stat/statm更具可讀性
/proc/self 鏈接到當前正在運行的進程

查看 /proc/[pid]/status,沒有異常

Name:   java
Umask:  0002
State:  S (sleeping)
Tgid:   6545
Ngid:   0
Pid:    6545
PPid:   1
TracerPid:      0
Uid:    1001    1001    1001    1001
Gid:    1001    1001    1001    1001
FDSize: 256
Groups: 27 1001
NStgid: 6545
NSpid:  6545
NSpgid: 6545
NSsid:  30676
VmPeak:  5710304 kB
VmSize:  5710304 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:   1026260 kB
VmRSS:   1020728 kB
RssAnon:         1002968 kB
RssFile:           17760 kB
RssShmem:              0 kB
VmData:  1364668 kB
VmStk:       132 kB
VmExe:         4 kB
VmLib:     17620 kB
VmPTE:      2488 kB
VmSwap:        0 kB
HugetlbPages:          0 kB
CoreDumping:    0
Threads:        45
SigQ:   0/31804
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 2000000181005ccf
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
NoNewPrivs:     0
Seccomp:        0
Speculation_Store_Bypass:       thread vulnerable
Cpus_allowed:   f
Cpus_allowed_list:      0-3
Mems_allowed:   00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list:      0
voluntary_ctxt_switches:        1
nonvoluntary_ctxt_switches:     0

查看 /proc/[pid]/cwd/,鏈接了執行目錄,看不出特別的。

查看 /proc/[pid]/task/,鏈接了子進程,看不出異常。

jvm 堆棧信息查看

# 查看 java 進程
jps

# 查看堆內存,用於定位死鎖
jstack -l [pid]

也可以使用這個方法查看,參考鏈接:Java程序卡住問題的解決
kill -3 [pid]
kill命令只能在linux下面用,其實也可以用jdk自帶的工具,比如用jstack去查看線程運行情況,這樣在windows下面也可以使用。

總結:Java是一個很開放的程序,對於出問題的情況利用提供的工具大部分都很容易定位。這中間一是你要知道有什麼樣的工具可以輔助你,至少你要把jdk/bin下面自帶的工具看一遍;另外就是要有藉助工具解決問題的意識,如果還是和剛開始學寫代碼的時候就知道到處打印輸出的語句,那解決問題的層次實在是太低了,也很難把問題真正解決。

Java Thread State

以下參考鏈接: 各種 Java Thread State 第一分析法則
4,如果大量線程在“waiting on condition”:
可能是它們又跑去獲取第三方資源,尤其是第三方網絡資源,遲遲獲取不到Response,導致大量線程進入等待狀態。
所以如果你發現有大量的線程都處在 Wait on condition,從線程堆棧看,正等待網絡讀寫,這可能是一個網絡瓶頸的徵兆,因爲網絡阻塞導致線程無法執行。

Summary

最終在 jstack 中定位到了卡住的位置,是網卡多 ip 綁定導致的,作相應調整即可。另,引言中定位 Java 的思路值得借鑑。

"spring.cloud.inetutils" #12 daemon prio=5 os_prio=0 tid=0x00007f99a466a000 nid=0x482b waiting on condition [0x00007f998756d000]
   java.lang.Thread.State: WAITING (parking)
  at sun.misc.Unsafe.park(Native Method)
  - parking to wait for  <0x0000000083e37c70> (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)

Reference

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章