今天線上一個java進程cpu負載100%。按以下步驟查出原因。
1.執行top -c命令,找到cpu最高的進程的id
2.執行top -H -p pid,這個命令就能顯示剛剛找到的進程的所有線程的資源消耗情況。找到CPU負載高的線程tid 8627, 把這個數字轉換成16進制,21B3(10進制轉16進制,用linux命令: printf %x 172)。
3.執行jstack -l pid,拿到進程的線程dump文件。這個命令會打出這個進程的所有線程的運行堆棧。
4.用記事本打開這個文件,搜索“21B3”,就是搜一下16進制顯示的線程id。搜到后,下面的堆棧就是這個線程打出來的。排查問題從這里深入。
今天最后排查出來的結果是“VM THREAD”把進程的資源耗盡。那只能說明是jvm在耗cpu。很容易想到是瘋狂的GC,按關鍵字 “overhead” 搜一下系統日志, 發現 “java.lang.OutOfMemoryError: GC overhead limit exceeded”日志。問題明了了。jvm在瘋狂的Full GC,而且有個大對象始終根節點路徑可達,無法釋放。dump了一下這個實例的內存,發現確實有大對象,占用了一個多G的堆內存。