jstack實戰點睛

2021-08-14 01:28:11 字數 1321 閱讀 6179

這裡吐槽下一下ios和android前端開發的朋友,他們總是厭倦使用debug除錯,而是像寫js指令碼的h5工程師似的,只使用log.info(「1」)、log.info(「2」)、log.info(「3」),這種資訊量很小的除錯方式。而且覺得debug很麻煩,只能說且行且珍惜。

不論除錯,或是解決問題,解決的好壞,解決的速度,很大程度取決於獲取到的資訊量的多少。

jstack用法很簡單乙個命令就可以了

jastack > jstack.log
一般發生在系統cpu飆高的情況下,步驟大致如下:

1.top命令檢視耗時最大的程序;

2.ps命令檢視耗時最大的程序;

3.執行緒id,轉換成16進製制數;

4.jstack列印執行緒棧,檢視對應的執行緒在做什麼事情;

一般發生在我們的某個請求特別慢的情況下,需要檢視到底在什麼位置卡住了,常見的是在連線db、nosql、zk、redis等的位置發生。

做法也很簡單,仍然是jstack列印執行緒棧,然後檢視waiting的執行緒,重點檢視包含自己**行的方法呼叫棧。

問題90%以上是出在自己的**上的,當然也不排除第三方庫的可能性,比如mongodb連線不上的時候就會導致cpu飆高。

情況是線上的伺服器gc特別頻繁,cpu使用率很高。我們首先檢視的是gc頻繁問題,這種問題一般是存在記憶體的物件的頻繁建立,導致記憶體溢位。

通過mat工具對jmap獲取到的記憶體棧進行分析,比較容易找到可疑的物件,比如這張圖:

最大的可疑物件就是mongo,所以我們應該從mongo相關的邏輯下手找問題。

通過進一步的jstack列印執行緒棧,會發現mongo一直執行在建立連線的位置,如下圖:

那麼接下來的事情就是,確認哪乙個mongo的位址連線不上了,問題也就能夠迎刃而解。

這個問題,你可能會想為什麼沒有看日誌,解決問題第一的第一就是看日誌啊!!為什麼沒有從日誌找到答案,而是繞了這麼大的圈子呢?實際上這是mongo的乙個經典問題,當連線不上的時候,他不認為是乙個要阻斷系統的致命問題,所以沒有做為嚴重的異常丟擲,必須開啟debug日誌級別才能看到相關的異常日誌。

當遇到這種情況,第一就是列印執行緒棧,實在定位不了在增加log輸出。

這裡看乙個執行緒棧可以定位的場景:

jvm 監控指令 jstack

格式 jstack option vmid 選項 l 除了堆疊資訊外,顯示關於鎖的附加資訊。作用 生成虛擬機器當前時刻的執行緒快照。目的 定位執行緒長時間停頓的原因,比如執行緒間死鎖 死迴圈 請求外部資源導致的長時間等待。使用步驟 1.得到執行緒快照。sudo u tomcat jstack l 程...

jvm 監控指令 jstack

格式 jstack option vmid 選項 l 除了堆疊資訊外,顯示關於鎖的附加資訊。作用 生成虛擬機器當前時刻的執行緒快照。目的 定位執行緒長時間停頓的原因,比如執行緒間死鎖 死迴圈 請求外部資源導致的長時間等待。使用步驟 1.得到執行緒快照。sudo u tomcat jstack l 程...

jvm 監控指令 jstack

格式 jstack option vmid 選項 l 除了堆疊資訊外,顯示關於鎖的附加資訊。作用 生成虛擬機器當前時刻的執行緒快照。目的 定位執行緒長時間停頓的原因,比如執行緒間死鎖 死迴圈 請求外部資源導致的長時間等待。使用步驟 1.得到執行緒快照。sudo u tomcat jstack l 程...