大家好!我是Sean!
相信很多C++程序員都經歷程序占用cpu過高的問題,這種問題,如果對代碼運行邏輯足夠熟悉,只靠腦子想估計定位起來也不難,但是如果是調用第三方sdk,或者團隊其他人開發的庫導致的cpu占用居高,就不那么容易定位了。
今天就分享一下我在工作中如何操作的!
如何確定程序cpu占用情況?
這個非常簡單,一條命令搞定,top -p 進程pid,這樣就可以:
這樣就可以持續的觀察你的程序的cpu占用情況,如果一直居高不下,就可能是有問題了。從圖中可以看到%CPU為98.0,這已經非常非常高了。
如何查看線程級別的cpu占用情況?
方法一:
命令:
ps H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=%cpu | grep 進程號
這個比較長,理解一下也不難記憶,這里我們可以看到用戶、進程號、父進程號、線程號、cpu占用總時長、cpu占用率、程序名。按照cpu的值進行了升序排列,最后一個即為占用cpu最高的線程,這樣就可以找到對應線程號。
圖中第4列就是線程號,第5列是cpu占用時長,第6列是cpu占用率,可以看到54313線程占用CPU最高。
方法二:
命令:
top -H -p 進程號
-H :Threads-mode operation
-p :Monitor-PIDs
這個就很好記了,推薦用這個!一目了然,動態顯示各個線程的cpu占用情況,很容易找出最高的那個。
圖中%CPU列很清晰的列出了cpu的占用狀況,也可以看出54313線程占用cpu最高。
細心的同學發現了,為什么這兩種方法得到的數據不一樣?莫非不對?其實都是對的,只是計算用的數據不同,top得到的是瞬時的cpu占用率,top數據默認3秒刷新一次,所以計算的是這3秒內線程占用CPU時長占比,而ps計算的是從啟動到現在的一個時長占比,運行時間越長,就會趨近於某個固定值,感興趣的同學可以了解一下cpu占用率的算法。
如何將問題定位到代碼行級別?
通過上面的操作我們已經找到了那個搞事情的線程,但是線程長得都一個鬼樣子,我們只能看到一個代表它的數字,此時需要一個建立一個線程號與具體代碼的映射關聯,那么就需要用到這幾個查看堆棧信息的強大工具了。
gstack/pstack(c/c++程序)
命令:
gstack/pstack 進程號
這兩個其實一個工具,pstack是gstack的軟連接而已。
jstack(java程序)
命令:
jstack 進程號
如果線程比較多,重定向到一個文本文件吧,gstack 進程號 >gstack.txt,方便查看。這個文本文件里存放的就是線程號和調用堆棧一對一的映射,這樣我們就可以很容易找到具體出問題的代碼,建議多抓取幾次,如果每次都是一樣的調用堆棧,基本可以確定就是那塊代碼出的問題了。
經過這樣一番操作,定位cpu占用高的問題就能迅速定位啦!
今天就分享到這里啦!感謝大家!覺得有用的話,幫忙點個贊唄~
掃碼關注我的公眾號,文章第一時間發布在公眾號平台。