📫作者簡介:小明java問道之路,2022年度博客之星全國TOP3,專注于后端、中間件、計算機底層、架構設計演進與穩定性建設優化,文章內容兼具廣度、深度、大廠技術方案,對待技術喜歡推理加驗證,就職于知名金融公司后端高級工程師。
? ? ? ??
📫 熱衷分享,喜歡原創~ 關注我會給你帶來一些不一樣的認知和成長。
? ? ? ??
🏆 2022博客之星TOP3 | CSDN博客專家 | 后端領域優質創作者 | CSDN內容合伙人
🏆 InfoQ(極客邦)簽約作者、阿里云專家 | 簽約博主、51CTO專家 | TOP紅人、華為云享專家
????????
🔥如果此文還不錯的話,還請👍關注、點贊、收藏三連支持👍一下博主~?
🍅 文末獲取聯系 🍅??👇🏻 精彩專欄推薦訂閱收藏 👇🏻
專欄系列(點擊解鎖)
學習路線(點擊解鎖)
知識定位
🔥Redis從入門到精通與實戰🔥
Redis從入門到精通與實戰
圍繞原理源碼講解Redis面試知識點與實戰
🔥MySQL從入門到精通🔥
MySQL從入門到精通
全面講解MySQL知識與企業級MySQL實戰 🔥計算機底層原理🔥
深入理解計算機系統CSAPP
以深入理解計算機系統為基石,構件計算機體系和計算機思維
Linux內核源碼解析
圍繞Linux內核講解計算機底層原理與并發
🔥數據結構與企業題庫精講🔥
數據結構與企業題庫精講
結合工作經驗深入淺出,適合各層次,筆試面試算法題精講
🔥互聯網架構分析與實戰🔥
企業系統架構分析實踐與落地
行業最前沿視角,專注于技術架構升級路線、架構實踐
互聯網企業防資損實踐
互聯網金融公司的防資損方法論、代碼與實踐
🔥Java全棧白寶書🔥
精通Java8與函數式編程
本專欄以實戰為基礎,逐步深入Java8以及未來的編程模式
深入理解JVM
詳細介紹內存區域、字節碼、方法底層,類加載和GC等知識
深入理解高并發編程
深入Liunx內核、匯編、C++全方位理解并發編程
Spring源碼分析
Spring核心七IOC/AOP等源碼分析
MyBatis源碼分析
MyBatis核心源碼分析
Java核心技術
只講Java核心技術
本文目錄
本文導讀
一、CPU利用率飆高問題
1、CPU利用率飆高定位步驟
2、CPU飆高的原因
3、CPU飆高的解決方法
二、內存飆高問題
1、內存飆高定位步驟
2、內存飆高故障分析及解決
2.1、進程占用太多的內存
2.2、緩存占用過高導致內存不足
2.3、內存泄漏和內存溢出
總結
本文導讀
本文對CPU利用率飆高問題,內存飆高問題進行剖析。主要內容有CPU利用率飆高定位步驟、CPU飆高的原因與解決;內存飆高定位步驟以及內存飆高故障分析及解決。
一、CPU利用率飆高問題
1、CPU利用率飆高定位步驟
當cpu經常飆升到100%的使用率,需要定位到具體是哪個線程在占用,定位問題的步驟如下(linux系統):
1、使用top命令常看當前服務器中所有進程(jps命令可以查看當前服務器運行java進程),找到當前cpu使用率最高的進程,獲取到對應的pid;
2、然后使用top -Hp pid,查看該進程中的各個線程信息的cpu使用,找到占用cpu高的線程pid。
3、使用jstack pid打印它的線程信息,通過jstack命令打印的線程號和通過top -Hp打印的線程號進制不一樣,需要進行轉換才能進行匹配,jstack中的線程號為16進制,而top -Hp打印的是10進制。
使用 jastack 命令分析線程信息的時候需要關注線程對應的運行狀態:runnable代表當前線程正在運行,waiting代表當前線程正在等待,該狀態需要進行特殊關注wait fot 后面的線程號,因為如果當前處于waiting狀態的程序長時間處于等待狀態,那么就需要知道它在等待哪個線程結束,也就是wait for后面的線程號,然后根據線程號找到對應的線程,去查看當前線程有什么問題。
2、CPU飆高的原因
1、無限循環或死循環:程序中存在錯誤的循環結構,導致程序一直在循環執行,從而消耗大量的CPU資源。
2、復雜的算法和計算:程序中執行復雜的算法、大規模的數據處理或者需要大量計算的操作可能導致CPU占用過高。
2、頻繁的IO操作:如果程序頻繁地進行文件讀寫、網絡通信等IO操作,可能會導致CPU占用增加。
3、線程問題:多線程程序中,線程可能因為競爭條件、死鎖、阻塞等問題導致CPU占用過高。
4、內存問題:內存泄漏或內存占用過高可能導致Java虛擬機頻繁進行垃圾回收,從而增加CPU負擔。
5、不合理的資源管理:沒有正確釋放或管理資源,如打開的文件、數據庫連接等,可能導致CPU占用過高。
6、第三方庫或框架問題:使用的第三方庫、框架或組件可能存在性能問題,導致程序CPU占用增加。
7、并發問題:不正確的并發控制或同步機制可能導致競爭條件和性能問題。
8、緩存問題:緩存未有效利用,導致程序頻繁地從內存或磁盤讀取數據,增加了CPU負擔。
9、頻繁的異常處理:頻繁的異常處理可能會導致CPU占用過高,因為異常處理可能會涉及昂貴的堆棧跟蹤等操作。
3、CPU飆高的解決方法
1、優化代碼:檢查代碼(code review),優化算法、循環和IO操作,減少CPU負擔。
2、線程管理:確保多線程程序中的線程正確管理,避免競爭條件和死鎖。
3、內存管理:檢查內存泄漏,確保釋放不再使用的內存。
4、使用合適的工具:使用性能分析工具來檢測CPU占用過高的具體位置和原因。
二、內存飆高問題
內存飆高一般都是堆中對象無法回收造成,因為java中的對象大部分存儲在堆內存中。其實也就是常見的oom問題(Out Of Memory)。
查看內存狀態的命令(top、free、vmstat,sar,/proc/meminfo)
導致內存不足的三個原因(進行占用太高、緩存占用過高沒有進行釋放、內存泄漏和內存溢出導致內存不足)
1、內存飆高定位步驟
1.jinfo pid,可以查看當前進行虛擬機的相關信息列舉出來
2.jstat -gc pid ms,多長毫秒打印一次gc信息,打印信息如下,里面包含gc測試,年輕代/老年帶gc信息等:
3.jmap -histo pid | head -20,查找當前進程堆中的對象信息,jmap -dump:format=b,file=xxx pid,可以生成堆信息的文件,但是這個命令不建議在生產環境使用,因為當內存較大時,執行該命令會占用大量系統資源,甚至造成卡頓。
在項目啟動時添加下面的命令,在發生oom時自動生成堆信息文件:-XX:+HeapDumpOnOutOfMemory。如果需要在線上進行堆信息分析,如果當前服務存在多個節點,可以下線一個節點,生成堆信息,或者使用第三方工具,阿里的arthas。
2、內存飆高故障分析及解決
2.1、進程占用太多的內存
原因:每當對磁盤進行讀寫操作時,都會先對緩存進行操作,因為緩存是需要消耗內存的,雖然緩存中的內存會自動釋放,但是只有當物理空閑內存不夠的時候,緩存中才會釋放一些內存出來,釋放的也僅僅是夠用,不會全部釋放。
解決辦法:使用top命令查看哪個進程占用太多,進行內存排序,kill掉
2.2、緩存占用過高導致內存不足
同進程占用太多的內存處理
2.3、內存泄漏和內存溢出
內存泄漏:程序在申請內存后,無法釋放,會導致內存空間不足。
內存溢出:程序申請內存時,沒有足夠的空間供其使用,出現內存溢出。(解決:檢查錯誤日志,修改JVM啟動參數,增加內存,)
內存溢出的原因:內存中加載的數據過于龐大,如一次從數據庫讀取過多的數據,內存供給不足,導致內存溢出;集合類中有對對象的引用,使用完后未清空,使得JVM(運行java代碼的容器,相當于一臺java虛擬機)不能回收;代碼中存在死循環或循環產生過多重復的對象實體;啟動參數內存設定的過小。
總結
本文對CPU利用率飆高問題,內存飆高問題進行剖析。主要內容有CPU利用率飆高定位步驟、CPU飆高的原因與解決;內存飆高定位步驟以及內存飆高故障分析及解決。