Java Thread Dump – 系統卡死、CPU 100%等問題的診斷工具

转自: http://blog.ragic.com/tw/java-thread-dump/



好幾次筆者跟一些有滿多年Java開發經驗的朋友聊到如何去診斷系統為什麼會卡住、系統為什麼會突然很慢、為什麼突然會一直吃掉100%的CPU等問題。 滿驚訝的發現,不知道怎麼使用thread dump這樣的工具來確認系統停在哪一行的人,比率還相當的高!有了這樣的工具,可以大大簡短系統問題分析的時間。

Thread dump簡單的說就是把目前所有JVM裡面正在跑、正在等待的thread執行的stack trace通通印出來,就跟一般我們在作Exception.printStackTrace印出來的東西類似。但是你可以在系統正在執行的狀態,去主動叫系統印出這樣的資訊,這時候我們就可以看每一個thread目前正在執行什麼東西,有哪些看起來比較可疑,可能是出問題的地方。

首先要怎麼樣產生thread dump呢?在Linux底下,可以使用” kill -QUIT <process_id>”的指令,針對目前正在執行的Java程式process id來下產生thread dump指令。如果在Windows底下,就在正在執行這個java程式的視窗底下,按下<ctrl><break>,便會產生 他的thread dump。而thread dump通常會出現在系統的標準輸出裡面。

要怎麼樣來研讀stack trace呢?以下是一個thread dump的例子:

"Thread-5" (TID:0xee703b78, sys_thread_t:0xee261db8, state:R) prio=5
        mythread.stopper(exec3.java:10)
        mythread.run(exec3.java:16)
    "Thread-4" (TID:0xee703bb8, sys_thread_t:0xee291db8, state:R) prio=5 *current thread*
        mythread.stopper(exec3.java:10)
        mythread.run(exec3.java:16)
    "Finalizer thread" (TID:0xee700220, sys_thread_t:0xee2c1d b8, state:R) prio=1
    "Async Garbage Collector" (TID:0xee700268, sys_thread_t:0 xee2f1db8, state:R) prio=1
    "Idle thread" (TID:0xee7002b0, sys_thread_t:0xee3c1db8, state:R) prio=0
    "Clock" (TID:0xee700088, sys_thread_t:0xee3f1db8, state:CW) prio=12
    "main" (TID:0xee7000b0, sys_thread_t:0x693a0, state:CW) prio=5
        exec3.main(exec3.java:32)
Monitor Cache Dump:
    mythread@EE703BB8/EE74E190: owner "Thread-4" (0xee291db8, 1 entry)
    mythread@EE703B78/EE74E270: owner "Thread-5" (0xee261db8, 1 entry)
    <unknown key> (0x693a0): <unowned>
        Waiting to be notified:
            "main" (0x693a0)
Registered Monitor Dump:
    Thread queue lock: <unowned>
    Name and type hash table lock: <unowned>
    String intern lock: <unowned>
    JNI pinning lock: <unowned>
    JNI global reference lock: <unowned>
    BinClass lock: <unowned>
    Class loading lock: <unowned>
    Java stack lock: <unowned>
    Code rewrite lock: <unowned>
    Heap lock: <unowned>
    Has finalization queue lock: <unowned>
    Finalize me queue lock: <unowned>
    Monitor IO lock: <unowned>
    Child death monitor: <unowned>
    Event monitor: <unowned>
    I/O monitor: <unowned>
    Alarm monitor: <unowned>
        Waiting to be notified:
            "Clock" (0xee3f1db8)
    Sbrk lock: <unowned>
    Monitor registry: owner "Thread-4" (0xee291db8, 1 entry)
Thread Alarm Q:
    sys_thread_t 0x693a0   [Timeout in 9997374 ms]

首先我習慣找的是,裡面有沒有正在執行我們自己寫的程式,畢竟錯出在自己身上的機率,常常還是比較大一些。接下來可以找有標明*current thread*或是state=R (Runnable)狀態的thread,這代表他們正在執行中,系統的問題也可能出現在他們身上。

有時候這樣還是沒辦法來確認問題到底出在哪,畢竟常常比較大型一點的系統,同時在跑的thread非常多,要猜說問題在哪裡可能要猜很久。另外一個會使用的技巧是,在系統正常的時候產生幾個thread dump,另外在系統不正常的時候也產生幾個thread dump。如此一來我們可以比對一下系統正常與不正常的時候的差異,有哪些thread在某些行的程式特別會出現在有問題的系統狀態,而這往往會是問題的 來源。

過去筆者用了這樣的方式省去了非常多分析系統問題的時間,無論是找找到底是哪個豬頭(自己?)弄了一個跑不完的無限迴圈,還是被剛剛更新的某個library害的。Thread dump相信會是您分析這類型比較非功能性的系統問題的好工具。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值