摘要:快照,帶線程命令,是顯示全部進(jìn)程,是顯示線程,全格式輸出顯示進(jìn)程樹,不加顯示所有實時快照推薦程度按數(shù)字從小到大。
有時候好好的程序放到生產(chǎn)服務(wù)器上一段時間后,就會發(fā)現(xiàn)服務(wù)器響應(yīng)緩慢,進(jìn)而進(jìn)一步發(fā)現(xiàn)是cpu過高,于是就慌了,造成cpu過高的原因很多,不過大多是由于資源吃緊造成,例如:sql執(zhí)行過慢,程序里存在死循環(huán),數(shù)據(jù)庫連接未釋放,網(wǎng)絡(luò)阻塞導(dǎo)致的第三方框架代碼出現(xiàn)死循環(huán),大量的操作導(dǎo)致死鎖等
案例:死循環(huán)造成CPU過高public class CpuTest { public static void main(String[] args) throws InterruptedException { loop(); endlessLoop(); } public static void endlessLoop() throws InterruptedException { while (true) { System.out.println("hello world! loop!"); } } public static void loop(){ for (int i = 0; i < 10000; i++) { System.out.println("hello world! endless loop!"); } } }
分析點擊抽樣器->CPU->查看CPU樣例,發(fā)現(xiàn)endlessLoop()方法最耗CPU(這里有2個方法 loop和endlessLoop)
查看線程cpu耗時,發(fā)現(xiàn)main線程最耗時,點擊增量,可以從此刻觀察,cpu耗時的增長速率
查看線程dump,主要觀察main線程,發(fā)現(xiàn)main線程當(dāng)前狀態(tài)下一直在執(zhí)行CpuTest.endlessLoop(CpuTest.java:14),這里可以定位問題位置,同時細(xì)心的童鞋可以觀察看后面執(zhí)行System.out.println("");方法是要先加鎖的。
截圖一段,我生產(chǎn)服務(wù)器(tomcat+springmvc)main線程的情況,其實只想說明web項目啟動的main方法在中間件里。
VisualVm只能定位JVM的cpu情況,但是生產(chǎn)主機(jī)上不光是Java程序,這時我們要采取另外的方案。
1.看監(jiān)控數(shù)據(jù)是否正常,cpu,mem。
CPU占用1.5左右(100-98.0id) 內(nèi)存占用50%(435/100*100%=43.5%) 阿里云監(jiān)控內(nèi)存大小轉(zhuǎn)成實際占用內(nèi)存大小,類似windows ,平均負(fù)載 0.1 差不多,其他幾個參數(shù),這里暫不介紹。
2.假設(shè)異常,找到異常的PID。
這里推薦htop(清晰進(jìn)程,線程,命令行,排序支持鼠標(biāo)雙擊,過濾,kill程序,標(biāo)記某個線程或者進(jìn)程,安裝apt-get install htop)
如果你沒有服務(wù)器上安裝軟件的權(quán)限的話,就老老實實用top。通過top命令(默認(rèn)3秒刷新,回車空格手動刷新,top -d 5 5秒刷新,也可以進(jìn)入top后輸入d設(shè)置刷新時間,top -p 4360 監(jiān)控指定進(jìn)程),然后按X ,默認(rèn)按照CPU%排序,查看系統(tǒng)運行情況,如果想強(qiáng)制按CPU 降序,則輸入大寫P,如果強(qiáng)制按內(nèi)存降序,則輸入大寫M(top命令是交互式的)。
解讀:
1).現(xiàn)在系統(tǒng)時間 10:18.44 ,系統(tǒng)一直運行了 131天16小時51分,當(dāng)前有1個用戶登錄系統(tǒng)(相同賬號也算不同用戶),平均負(fù)載分別為0.00,0.01,0.05(分別為1分鐘,5分鐘,15分鐘的負(fù)載情況,load average是每隔5秒鐘檢查一次活躍的進(jìn)程數(shù),用特定的算法得到的數(shù)值,然后除以邏輯CPU數(shù)量,如果負(fù)載持續(xù)大于cpu個數(shù),則表明負(fù)載過高) 。大概可以看出系統(tǒng)負(fù)載很低,運行狀態(tài)健康。
2).當(dāng)前一共有103個進(jìn)程,處于運行的有2個,處于休眠狀態(tài)的有101個,處于停止?fàn)顟B(tài)的有0個,處于僵尸狀態(tài)的有0個。大概可以看出系統(tǒng)進(jìn)程總數(shù)較少,環(huán)境比較單純,運行中的進(jìn)程不多。
3).0.3 us 用戶空間占用CPU 0.3%,0.7 sy內(nèi)核占用CPU 0.7%,0.0 ni改變過優(yōu)先級的進(jìn)程占用CPU的百分比,98.0 id空閑CPU的百分比為98.0,0.3 waIO等待所占用CPU的百分比為0.3,0.3 hi硬中斷(Hardware IRQ)占用CPU的百分比為0.3(外設(shè)給CPU的異步信號(中斷),例如:網(wǎng)卡收到數(shù)據(jù)包),0.0 si軟中斷占用cpu的百分比為0(軟件本身給操作系統(tǒng)內(nèi)核的中斷信號,通常由硬中斷處理程序?qū)Σ僮飨到y(tǒng)內(nèi)核的中斷),0.3 st 虛擬機(jī)被hypervisor偷去CPU的時間。
4).KiB Mem 代表內(nèi)存占用,1016272 total 內(nèi)存總的大小1g(以kb為單位),941492 used 使用中的內(nèi)存總量為0.9g,74780 free空閑內(nèi)存總量為74m(嚇一跳吧,才74M,這個不是實際剩余的內(nèi)內(nèi)存大小),115900 buffers緩存的內(nèi)存量為115m,389836 cached cached大小380M。空閑內(nèi)存總量只有74m,如果是windows去理解的話,此臺服務(wù)器已經(jīng)快掛了,實際內(nèi)存大小等于74M+ buffers+cached = 580m(哈哈,夠用,才占用一半呢), linux的內(nèi)存管理和windows是不一樣的,Linux會借用空閑的內(nèi)存當(dāng)作磁盤緩存, 磁盤數(shù)據(jù)緩存會讓linux運行的更快,它永遠(yuǎn)不會從程序中拿出內(nèi)存,它沒有任何缺點,只是會混淆新手,如果你的應(yīng)用程序需要更多的內(nèi)存,他們會回收一部分用作磁盤數(shù)據(jù)緩存的物理內(nèi)存,返回給應(yīng)用程序,這個過程不需要啟動交換,磁盤緩存(Disk caching)是不能禁用的, 但是可以釋放磁盤緩存 1).只釋放pagecache(文件緩存) echo 1 > /proc/sys/vm/drop_caches 2).釋放dentries和inodes echo 2 > /proc/sys/vm/drop_caches 3).釋放pagecache,dentries和inodes echo 3 > /proc/sys/vm/drop_caches
具體原理可以查看linuxatemyram
我們利用free 進(jìn)一步證實上面的內(nèi)容
1).shared代表被線程共享的內(nèi)存大小(大多數(shù)已經(jīng)舍棄掉),buffer用來給塊設(shè)備做緩存(記錄文件系統(tǒng)的metadata和tracking in flight pages),cache緩存文件(第二次打開就很快),linux系統(tǒng)cached比較大,cached大小390m,buffers為110m。
2).435288代表 -buffers/cache (應(yīng)用程序?qū)嶋H使用330m內(nèi)存) 580984 代表 +buffers/cache(實際剩余內(nèi)存大小580m)。
3).重要等式 total = used + free used(-buffers/cache) = used(Mem)-buffers(Mem)-cached(Mem) free(+buffers/cache) = free(Mem) + buffers(Mem) +cached(Mem) 。
4).free命令的值是從 /proc/meminfo 文件里讀到的。
5).Swap 交換區(qū) 總共大小 0 kb,已經(jīng)使用0kb,釋放了0Kb,如果swap used > 0,則可以說明系統(tǒng)內(nèi)存瓶頸了。
6).內(nèi)存總和 free -t 總和等于total(Mem) + total(Swap)。
7).一般常用命令 free -s 3 每3秒觀察一次內(nèi)存使用情況。
占用cpu最高的進(jìn)程是java,PID為28628,USER進(jìn)程所有者root,PR優(yōu)先級20,NI為0(負(fù)值優(yōu)先級高,正值優(yōu)先級低,PR=NI+20) ,VIRT進(jìn)程使用虛擬內(nèi)存1G(java進(jìn)程最高只能占用到1G),RES進(jìn)程實際使用的物理內(nèi)存270M(不包含swap和shared),SHR共享內(nèi)存大小5M,S進(jìn)程狀態(tài)隨眠狀態(tài)(S睡眠,R運行,T停止或被跟蹤,Z僵尸,D不可中斷睡眠態(tài)),%CPU占用CPU 0.7%,%MEM占用內(nèi)存27%,TIME+進(jìn)程使用cpu的時間54分40.12秒。總體看java進(jìn)程運行良好。
3.這里假設(shè)PID為16368的進(jìn)程占用CPU比較高(因為做了多次實驗,所以PID沒辦法和上面的28628保持一致),
先用ps -ef | grep java,也可以用htop filter java,也可以jps -v 找到 java的進(jìn)程ID 16368(只能查看當(dāng)前用戶的java pid,不太建議使用,-v顯示詳細(xì)信息,也可以不加)
?代表終端設(shè)備未知,Sl代表休眠狀態(tài)多線程
Linux通過進(jìn)程查看線程的方法 1).htop按t(顯示進(jìn)程線程嵌套關(guān)系)和H(顯示線程) ,然后F4過濾進(jìn)程名。2).ps -eLf | grep java(快照,帶線程命令,e是顯示全部進(jìn)程,L是顯示線程,f全格式輸出) 3).pstree -p
4.利用jstack 16368 > 2016-1-21.tdump (jstack是jdk自帶的生成java stack和native stack的工具) 把threaddump輸出到文件里,這里假設(shè)PID為16369(一般比進(jìn)程號+1的是main線程,如果存在main線程貌似最先分配)的線程占用CPU最高,將其ID轉(zhuǎn)成16進(jìn)制0x3ff1(使用命令 printf "%x " 16369 輸出3ff1)。
5.搜索threaddump文件,nid= 0x3ff1的線程堆棧,通過堆棧信息,就可以定位到占用CPU最高的代碼地方(這里是正常的)。
好啦,CPU沖高問題排查完畢,有了這樣的知識體系,以后完全可以舉一反三,coder君同時附上其他常用配合命令。
每隔一秒顯示新生代,老年代,持久代垃圾回收情況
jstat -gcutil 16368 1000ms 參考jstat -help,也可以查看遠(yuǎn)程主機(jī)的GC情況,需要遠(yuǎn)程主機(jī)開啟jstatd服務(wù)。
觀察堆內(nèi)存情況
jmap -dump:format=b,file=2016-1-21.mdump 16368 生成堆dump,放到mat或者vvm進(jìn)行分析,上篇分析OOM有講到。
查看jvm系統(tǒng)參數(shù)
jinfo 16368
參考資料性能分析神器VisualVM
vvm命令
感謝您的耐心閱讀,如果您發(fā)現(xiàn)文章中有一些沒表述清楚的,或者是不對的地方,請給我留言,你的鼓勵是作者寫作最大的動力,
如果您認(rèn)為本文質(zhì)量不錯,讀后覺得收獲很大,不妨小額贊助我一下,讓我更有動力繼續(xù)寫出高質(zhì)量的文章。
支付寶
微信
作 者 : @mousycoder
原文出處 : http://mousycoder.com/2016/02...
創(chuàng)作時間:2016-2-14
更新時間:2016-2-14
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/65479.html
摘要:是代表的主機(jī)第一個請求服務(wù),使用線程池,生成一個單獨的線程來處理請請求。單個線程詳細(xì)的數(shù)據(jù)查看線程的堆棧生成某個時刻的線程這些線程的來由一清二楚,很快就能定位問題所在。 VisualVM提供分析圖形化監(jiān)控線程的運行狀態(tài),有時候可能不是我們自己代碼沒寫好造成資源的浪費,而是系統(tǒng)引入了很多第三方包(也包括容器)的時候,他們可能私自建立線程,如果邏輯處理不當(dāng),可能會造成資源的浪費。 以下均用...
摘要:點擊進(jìn)入我的博客命令行工具這些工具大多數(shù)是類庫的一層薄的包裝,它們的主要功能代碼是在類庫中實現(xiàn)的。可視化工具是到目前為止隨發(fā)布的功能最強(qiáng)大的運行監(jiān)視和故障處理程序,并且可以預(yù)見在未來一段時間內(nèi)都是官方主力發(fā)展的虛擬機(jī)故障處理工具。 點擊進(jìn)入我的博客 3.1 JDK命令行工具 showImg(https://segmentfault.com/img/remote/14600000174...
摘要:垃圾回收監(jiān)控和分析工具是在安裝時免費提供的。監(jiān)控現(xiàn)在可以監(jiān)控垃圾回收過程了。至少我們可以知道程序中存在和對象內(nèi)存分配和垃圾回收相關(guān)的問題。到此為止,關(guān)于垃圾回收的系列文章已經(jīng)完結(jié)了。 本文非原創(chuàng),翻譯自Java Garbage Collection Monitoring and Analysis在Java中為對象分配和釋放內(nèi)存空間都是由垃圾回收線程自動執(zhí)行完成的。和C語言不一樣的是Ja...
摘要:是什么是自帶的一個用于程序性能分析的工具,安裝完畢后就有啦,在安裝目錄的文件夾下能找到名稱為。假設(shè)我自己實現(xiàn)了一個快速排序算法,我想測一測它的性能。首先我在下圖代碼第行執(zhí)行我的快速排序算法之處設(shè)置一個斷點。回到,按結(jié)束應(yīng)用程序的執(zhí)行。 VisualVM是什么? showImg(https://segmentfault.com/img/remote/1460000016730111); ...
摘要:并且分別給出了,線程的堆棧,就可以很快定位代碼。避免無限期等待當(dāng)一個線程必須等待另外一個線程的時候,最好加上一個等待時間。 運行了一段時間的程序,可能因為不小心的一些修改,造成死鎖,本人就VisualVM簡單的介紹下死鎖的檢測。 死鎖程序 package jvisualVM; public class DeadLock { public static void main(S...
閱讀 1135·2021-11-25 09:43
閱讀 1575·2021-10-25 09:47
閱讀 2471·2019-08-30 13:46
閱讀 758·2019-08-29 13:45
閱讀 1285·2019-08-26 13:29
閱讀 2994·2019-08-23 15:30
閱讀 1109·2019-08-23 14:17
閱讀 1331·2019-08-23 13:43