什麼是記憶體洩漏? 什麼是記憶體溢出
記憶體溢出: OutOfMemory
它是指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,抛出 OutOfMemory 錯誤
記憶體洩露: Memory Leak
它是指程式運作後,沒有釋放所占用的記憶體空間,比如程式運作完後沒有釋放對象的引用,一次記憶體洩漏可能不會有很大的影響,但長時間的記憶體洩漏,堆積到一定程度就會産生記憶體溢出
(1)單例對象,生命周期和應用程式一樣長,如果單例對象持有對外部對象的引用的話,那麼這個外部對象是不能被回收的,則會産生記憶體洩露;
(2)一些資源未閉也會導緻記憶體洩漏,比如資料庫連接配接,網絡連接配接 socket 和0 流的連接配接都必須在 finally 中 close,否則不能被回收的:
Linux環境下線上伺服器記憶體占用過高排查思路
- linux指令
>top
按記憶體占用将程式排序,找出記憶體占用高的程序,并記錄PIDshift+M
-
檢視jvm中占用記憶體較大的對象有哪些,資訊可能較多,可以将資訊輸出到某個檔案jmap -hosto PID
jmap -hosto PID >./檔案名.txt
-
檢視jvm堆記憶體的使用情況jmap -heap PID
-
jvm鏡像快照,執行這個導出指令時會占用一部分記憶體資源,是以操作時需要謹慎操作,如果時叢集部署可以先從叢集中摘除;盡量在啟動項目時添加jmap-dump:format=b,file=./檔案名.hprof PID
和-XX:+HeapDumpOnOutofMemoryError
,在發生堆記憶體溢出時,自動導出并儲存記憶體鏡像,-XX:HeapDumpPath=/路徑/檔案名.hprof
MAT使用
CPU占用過高問題排查
- linux指令
>shift+P按記憶體占用将程式排序,找出CPU占用高的程序,并記錄PIDtop
- linux指令
檢視PID程序内所有線程占用CPU及記憶體的占用情況,記錄占用較高的線程tidtop -H -p PID
- 用
輸出jvm的線程詳情jstack TID > ./檔案名.txt
- 因為輸出jvm線程資訊線程号是用16進制儲存的,是以要用
将tid轉換成16進制,然後再從第3步拿到的jvm線程詳情檔案中查找線程資訊中的業務類,找到類以後檢視對應類的代碼邏輯是否有問題printf '%x' tid
JVMI 堆溢出後,其他線程是否可以繼續工作
如果導緻記憶體占用對象是局部的,那麼發生記憶體溢出後,抛出異常後方法就出棧了,引用沒有了也就回收了,是以其他線程是可以繼續工作的;
但是如果導緻導緻記憶體占用高的對象是全局的,無法釋放,就會導緻其他線程無法通路