dump分析工具_Java應用CPU過高,如何排查?參考解決思路和常用工具總結

2ce58c46b0e701c7fc596b4fc89b0d66.png

本文總結了一些常見的線上應急現象和對應排查步驟和工具。分享的主要目的是想讓對線上問題接觸少的同學有個預先認知,免得在遇到實際問題時手忙腳亂。畢竟作者自己也是從手忙腳亂時走過來的。

只不過這里先提示一下。在線上應急過程中要記住,只有一個總體目標:盡快恢復服務,消除影響。不管處于應急的哪個階段,我們首先必須想到的是恢復問題,恢復問題不一定能夠定位問題,也不一定有完美的解決方案,也許是通過經驗判斷,也許是預設開關等,但都可能讓我們達到快速恢復的目的,然后保留部分現場,再去定位問題、解決問題和復盤

在大多數情況下,我們都是先優先恢復服務,保留下當時的異常信息(內存dump、線程dump、gc log等等,在緊急情況下甚至可以不用保留,等到事后去復現),等到服務正常,再去復盤問題。

edcb6840e56a9784d93700795f0308da.png

常見現象:CPU 利用率高/飆升

場景預設:

監控系統突然告警,提示服務器負載異常。

預先說明:

CPU飆升只是一種現象,其中具體的問題可能有很多種,這里只是借這個現象切入。

注:CPU使用率是衡量系統繁忙程度的重要指標。但是CPU使用率的安全閾值是相對的,取決于你的系統的IO密集型還是計算密集型。一般計算密集型應用CPU使用率偏高load偏低,IO密集型相反。

常見原因:

  • 頻繁 gc
  • 死循環、線程阻塞、io wait...etc

模擬

這里為了演示,用一個最簡單的死循環來模擬CPU飆升的場景,下面是模擬代碼,

在一個最簡單的SpringBoot Web 項目中增加CpuReaper這個類,

@Componentpublic?class?CpuReaper?{????@PostConstruct????public?void?cpuReaper()?{????????int?num?=?0;????????long?start?=?System.currentTimeMillis()?/?1000;????????while?(true)?{????????????num?=?num?+?1;????????????if?(num?==?Integer.MAX_VALUE)?{????????????????System.out.println("reset");????????????????num?=?0;????????????}????????????if?((System.currentTimeMillis()?/?1000)?-?start?>?1000)?{????????????????return;????????????}????????}????}}

打包成jar之后,在服務器上運行。java -jar cpu-reaper.jar

(1)第一步:定位出問題的線程

方法 a: 傳統的方法

1、top 定位CPU 最高的進程執行top命令,查看所有進程占系統CPU的排序,定位是哪個進程搞的鬼。在本例中就是咱們的java進程。PID那一列就是進程號。

f397ee835ac694750eb3dfe9eb705023.png

2、top -Hp pid 定位使用 CPU 最高的線程

64b8a14990eca10f3f29c2465a40494b.png

3、printf '0x%x' tid 線程 id 轉化 16 進制

>?printf?'0x%x'?12817>?0x3211

4、jstack pid | grep tid 找到線程堆棧

>?jstack?12816?|?grep?0x3211?-A?30
302f16482616d24b2dfbce11a6ea1be2.png

方法 b: show-busy-java-threads

這個腳本來自于github上一個開源項目,項目提供了很多有用的腳本,show-busy-java-threads就是其中的一個。使用這個腳本,可以直接簡化方法A中的繁瑣步驟。如下,

>?wget?--no-check-certificate?https://raw.github.com/oldratlee/useful-scripts/release-2.x/bin/show-busy-java-threads>?chmod?+x?show-busy-java-threads>?./show-busy-java-threads
show-busy-java-threads#?從所有運行的Java進程中找出最消耗CPU的線程(缺省5個),打印出其線程棧#?缺省會自動從所有的Java進程中找出最消耗CPU的線程,這樣用更方便#?當然你可以手動指定要分析的Java進程Id,以保證只會顯示你關心的那個Java進程的信息show-busy-java-threads?-p?show-busy-java-threads?-c?

方法 c: arthas thread

阿里開源的arthas現在已經幾乎包攬了我們線上排查問題的工作,提供了一個很完整的工具集。在這個場景中,也只需要一個thread -n命令即可。

>?curl?-O?https://arthas.gitee.io/arthas-boot.jar?#?下載

后續

通過第一步,找出有問題的代碼之后,觀察到線程棧之后。我們就要根據具體問題來具體分析。這里舉幾個例子。

1、情況一:發現使用CPU最高的都是GC 線程。

GC?task?thread#0?(ParallelGC)"?os_prio=0?tid=0x00007fd99001f800?nid=0x779?runnableGC?task?thread#1?(ParallelGC)"?os_prio=0?tid=0x00007fd990021800?nid=0x77a?runnable?GC?task?thread#2?(ParallelGC)"?os_prio=0?tid=0x00007fd990023000?nid=0x77b?runnable?GC?task?thread#3?(ParallelGC)"?os_prio=0?tid=0x00007fd990025000?nid=0x77c?runnabl

2、情況二:發現使用CPU最高的是業務線程

  • io wait
    • 比如此例中,就是因為磁盤空間不夠導致的io阻塞
  • 等待內核態鎖,如 synchronized
    • jstack -l pid | grep BLOCKED 查看阻塞態線程堆棧
    • dump 線程棧,分析線程持鎖情況。
    • arthas提供了thread -b,可以找出當前阻塞其他線程的線程。針對 synchronized 情況

常見現象:頻繁 GC

1、 回顧GC流程

在了解下面內容之前,請先花點時間回顧一下GC的整個流程。

7bde237f84b552fc1136d389c5974a97.png

接前面的內容,這個情況下,我們自然而然想到去查看gc 的具體情況。

  • 方法a : 查看gc 日志
  • 方法b : jstat -gcutil 進程號 統計間隔毫秒 統計次數(缺省代表一致統計
  • 方法c : 如果所在公司有對應用進行監控的組件當然更方便(比如Prometheus + Grafana)

這里對開啟 gc log 進行補充說明。一個常常被討論的問題(慣性思維)是在生產環境中GC日志是否應該開啟。因為它所產生的開銷通常都非常有限,因此我的答案是需要開啟。但并不一定在啟動JVM時就必須指定GC日志參數。

HotSpot JVM有一類特別的參數叫做可管理的參數。對于這些參數,可以在運行時修改他們的值。我們這里所討論的所有參數以及以“PrintGC”開頭的參數都是可管理的參數。這樣在任何時候我們都可以開啟或是關閉GC日志。比如我們可以使用JDK自帶的jinfo工具來設置這些參數,或者是通過JMX客戶端調用HotSpotDiagnostic MXBean的setVMOption方法來設置這些參數。

這里再次大贊arthas??,它提供的vmoption命令可以直接查看,更新VM診斷相關的參數。

獲取到gc日志之后,可以上傳到GC easy幫助分析,得到可視化的圖表分析結果。

f7903d9ac8275fb8f82251fd8292eabc.png

2、GC 原因及定位

prommotion failed

從S區晉升的對象在老年代也放不下導致 FullGC(fgc 回收無效則拋 OOM)。

可能原因:

  • survivor 區太小,對象過早進入老年代查看 SurvivorRatio 參數
  • 大對象分配,沒有足夠的內存dump 堆,profiler/MAT 分析對象占用情況
  • old 區存在大量對象dump 堆,profiler/MAT 分析對象占用情況

你也可以從full GC 的效果來推斷問題,正常情況下,一次full GC應該會回收大量內存,所以 正常的堆內存曲線應該是呈鋸齒形。如果你發現full gc 之后堆內存幾乎沒有下降,那么可以推斷:**堆中有大量不能回收的對象且在不停膨脹,使堆的使用占比超過full GC的觸發閾值,但又回收不掉,導致full GC一直執行。換句話來說,可能是內存泄露了。

一般來說,GC相關的異常推斷都需要涉及到內存分析,使用jmap之類的工具dump出內存快照(或者 Arthas的heapdump)命令,然后使用MAT、JProfiler、JVisualVM等可視化內存分析工具。

至于內存分析之后的步驟,就需要小伙伴們根據具體問題具體分析啦。

六、涉及工具

再說下一些工具。

  • Arthas
  • useful-scripts
  • GC easy
  • Smart Java thread dump analyzer - thread dump analysis in seconds
  • PerfMa - Java虛擬機參數/線程dump/內存dump分析
  • Linux 命令
  • Java N 板斧
  • MAT、JProfiler...等可視化內存分析工具

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457987.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457987.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457987.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

st官網下載stm32固件庫方法

進入www.st.com官網------把網站改成中文(就在右上方)----點擊產品-----選擇右側的微控制器選項------選擇左側的STM32 32位ARM CortexMCU-----選擇左側的STM32F1系列-----選擇STM32103-----選擇中間部分mcu對應型號(我用的是STM32F103ZE)---…

mysql5.5提示Deprecated: mysql_query(): The mysql extension is deprecated

解決方法1&#xff1a;在php程序代碼里面設置報警級別 <?php error_reporting E_ALL & ~E_DEPRECATED 方法2&#xff1a;禁止php報錯 display_errors On 改為 display_errors Off 方法3&#xff1a;使用mysqli或者PDO 建議大家盡快取消mysql&#xff0c;全部都走…

JavaScript強化教程 —— Cocos2d-JS極速調試技巧

本文為 H5EDU 機構官方 HTML5培訓 教程&#xff0c;主要介紹&#xff1a;JavaScript強化教程 —— Cocos2d-JS極速調試技巧 本文教大家一個調試Cocos2d-JS的小技巧&#xff0c;我都是這么用的&#xff0c;特意來告訴大家這個輕量快速的調試技巧。1.首先我們需要安裝官方的cocos…

dos攻擊命令_Kali Linux系列之拒絕服務攻擊(DOS)實戰(上)

(你的世界是個什么樣的世界&#xff1f;你說&#xff0c;我們傾聽!)-----------------小百科拒絕服務攻擊即是攻擊者想辦法讓目標機器停止提供服務&#xff0c;是黑客常用的攻擊手段之一。其實對網絡帶寬進行的消耗性攻擊只是拒絕服務攻擊的一小部分&#xff0c;只要能夠對目標…

stm32定時器配置

stm32通用定時器 STM32的定時器是個強大的模塊&#xff0c;定時器使用的頻率也是很高的&#xff0c;定時器可以做一些基本的定時&#xff0c;還可以做PWM輸出或者輸入捕獲功能。 時鐘源問題&#xff1a; 名為TIMx的有八個&#xff0c;其中TIM1和TIM8掛在APB2總線上&#xff0c;…

SQL 養成一個好習慣是一筆財富

來源&#xff1a;MR_ke 鏈接&#xff1a;http://www.cnblogs.com/MR_ke/archive/2011/05/29/2062085.html 我們做軟件開發的&#xff0c;大部分人都離不開跟數據庫打交道&#xff0c;特別是erp開發的&#xff0c;跟數據庫打交道更是頻繁&#xff0c;存儲過程動不動就是上千行&a…

【JAVA】StringTokenizer 迭代方式對字符串進行分割

StringTokenizer是一個用來分隔String的應用類&#xff0c;相當于VB的split函數。1.構造函數public StringTokenizer(String str)public StringTokenizer(String str, String delim)public StringTokenizer(String str, String delim, boolean returnDelims)第一個參數就是要分…

python數組定義_python定義數組

廣告關閉 騰訊云11.11云上盛惠 &#xff0c;精選熱門產品助力上云&#xff0c;云服務器首年88元起&#xff0c;買的越多返的越多&#xff0c;最高返5000元&#xff01; 一、一維數組 1. 直接定義matrix2. 間接定義matrixprint(matrix)輸出&#xff1a;3. 數組乘法matrix*5print…

Android-語言設置流程分析

Android手機語言切換行為&#xff0c;是通過設置-語言和輸入法-語言來改變手機的語言&#xff0c;其實這個功能很少被用戶使用。 以Android5.1工程源碼為基礎,從設置app入手來分析和學習語言切換的過程:一、語言設置界面&#xff1a;首先在設置app中找到語言設置這個Preference…

charles 安裝 ssl_最全面的解決Charles手機抓包的證書問題(步驟非常詳細)

源自公眾號文章: 徹底解決Charles手機抓包的證書問題簡介: Charles 抓包是日常開發當中經常會用到的技術, 在 Android 6 之前, 手機系統既信任系統內置的證書, 也信任用戶自己安裝的證書, 但是在 Android 7 之后, 卻發生了變化, 手機系統只信任系統內置的根證書. 當然了, 這是為…

oracle報錯:ORA-00054: 資源正忙,要求指定 NOWAIT

ORA-00054: 資源正忙, 但指定以 NOWAIT 方式獲取資源&#xff1a; --首先得到被鎖對象的session_idselect session_id from v$locked_object; --通過上面得到的session_id去取得v$session的sid和serial#&#xff0c;然后對該進程進行終止。--SELECT sid, serial#, username, o…

ARM中ROM,RAM,FLASH區別

RAM&#xff08;Random Access Memory&#xff09;的全名為隨機存取記憶體&#xff0c;它相當于PC機上的移動存儲&#xff0c;用來存儲和保存數據的。它在任何時候都可以讀寫&#xff0c;RAM通常是作為操作系統或其他正在運行程序的臨時存儲介質&#xff08;可稱作系統內存&…

excel 2007 vba與宏完全剖析_Excel宏VBA小技巧系列 | 分段加合

寫在前面的話 知識產權算是一個盛產數據的行業。專利啊商標啊著作啊&#xff0c;都有著錄項目。我們常說的專利分析、產業導航、企業導航、產業預警、競爭情報、技術綜述、知識產權評議等等&#xff0c;常規操作之一就要先處理著錄項目數據&#xff0c;然后再進行不同角度的分…

SecureCRT:保存輸出日志的方法

處理地址&#xff1a; http://blog.sina.com.cn/s/blog_64c1dd210101gzgz.html 或者&#xff1a; http://renchen.blog.51cto.com/4531967/1195862 重點在與設定文檔的文件名稱&#xff0c;里面有說明。 http://renchen.blog.51cto.com/4531967/1195862轉載于:https://www.cnbl…

redhat虛擬機安裝

做過好多使用VMware workstation虛擬機搭建的系統&#xff0c;這是我第一次使用Virtual Box&#xff0c;感覺跟Vmware差不多&#xff0c;我的本子的系統是win7 64位。 下面演示安裝的是在VirtualBox里安裝rhel 6.4 linux 64位系統。 一、VirtualBOX 版本。 二、虛擬機的配置。…

mysql 查看表v空間自增漲_MySQL InnoDB表空間加密

從 MySQL5.7.11開始&#xff0c;MySQL對InnoDB支持存儲在單獨表空間中的表的數據加密 。此功能為物理表空間數據文件提供靜態加密。該加密是在引擎內部數據頁級別的加密手段&#xff0c;在數據頁寫入文件系統時加密&#xff0c;加密用的是AES算法&#xff0c;而其解密是在從文件…

arm之mmu原理

實驗目的&#xff1a;啟用MMU&#xff0c;映射SDRAM的地址空間&#xff0c;操作虛擬地址實現“點燈大法”&#xff0c;借此掌握MMU的使用。實驗環境及說明&#xff1a;恒頤S3C2410開發板H2410。H2410核心板擴展有64MB的K4S561632 SDRAM(4M*16bit*4BANK)&#xff0c;地址范圍是0…

osal_start_timerEx(Lock_TaskID,SBP_START_DEVICE_EVT,SBP_PERIODIC_EVT_PERIOD)的理解

osal_start_timerEx(Lock_TaskID,SBP_START_DEVICE_EVT,SBP_PERIODIC_EVT_PERIOD)與osal_set_event(Music_TaskID,event)的區別是osal_start_timerEx周期性的一直推送事件周期時間由SBP_PERIODIC_EVT_PERIOD決定&#xff0c;而osal_set_event是只推送一次。osal_start_timerEx開…

ideaspringboot項目上傳服務器_PHP中使用 TUS 協議來實現可恢復文件上傳

曾經嘗試過用PHP上傳大文件嗎&#xff1f;想知道您是否可以從上次中斷的地方繼續上傳&#xff0c;而不會在遇到任何中斷的情況下再次重新上傳整個數據&#xff1f;如果您覺得這個場景很熟悉&#xff0c;請接著往下閱讀。文件上傳是我們幾乎所有現代Web項目中的一項很常見的任務…

無密碼登陸

server A /B以root賬戶在A上無密碼ssh到B方式一ON A:ssh-keygen -t dsa -P -f ~/.ssh/id_dsa cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys chmod 644 ~/.ssh/authorized_keys service sshd restart ON B:ssh-keygen -t dsa -P -f ~/.ssh/id_dsa cat ~/.ssh/id_d…