Java —— 内存泄露排查
最近發現服務器內存使用持續增長且增長速率大,懷疑是內存泄露導致的。
最終定位到是因為程序中存在線程池頻繁創建但未銷毀問題導致線程泄露,進而影響內存使用增長。
Tips:本文不記錄排錯過程,只記錄可疑點及排錯命令。
1. 套路
① 查看內存使用,對相隔一段時間的應用內存使用情況進行對比(top命令等),確認內存存在緩慢上升的情況
② jstat -gccapacity 【pid】查看JVM各部分內存使用增長是否符合top命令展示的應用內存使用增長。
-
如果符合,則使用MAT工具分析JVM堆棧情況,對比隔一段時間的堆棧對象增長情況,對于增加的對象進行內存泄露排查。
-
如不符合,這說明內存使用很大概率不是JVM堆棧導致的,可能程序中使用了堆外內存,堆外內存持續增長的這種情況不容易排查,最好開啟JVM的NMA功能,使用jcmd命令對堆外內存進行分析。
2. 常見堆外泄露
- JNI
- gzip
- 線程棧
- 不良代碼
- ThreadLocal
- NIO directbuffer泄漏
3. Linux內存相關概念
-
used區:應用實際占用內存,在+/-buffer計算方式下,used區=實際已用內存。而在Mem計算方式下,used=實際已有+Buffer+Cache (原因是Buffer和Cache在應用需要時會釋放出應用所需大小供應用使用,但是不會全部釋放)
-
free區:剩余空閑內存大小,未被應用used或被系統用于緩存(Cache/Buffer)的內存部分。
-
Cached區:這里的cache指Linux內存中的:Page cache。Page cache主要用來作為文件系統上的文件數據的緩存來用,尤其是針對當進程對文件有read/write操作的時候。如果你仔細想想的話,作為可以映射文件到內存的系統調用:mmap是不是很自然的也應該用到page cache?在當前的系統實現里,page cache也被作為其它文件類型的緩存設備來用,所以事實上page cache也負責了大部分的塊設備文件的緩存工作。
-
Buffer區:Buffer cache則主要是設計用來在系統對塊設備進行讀寫的時候,對塊進行數據緩存的系統來使用。這意味著某些對塊的操作會使用buffer cache進行緩存,比如我們在格式化文件系統的時候。
一般情況下兩個緩存系統是一起配合使用的,比如當我們對一個文件進行寫操作的時候,page cache的內容會被改變,而buffer cache則可以用來將page標記為不同的緩沖區,并記錄是哪一個緩沖區被修改了。這樣,內核在后續執行臟數據的回寫(writeback)時,就不用將整個page寫回,而只需要寫回修改的部分即可。 -
total:內存總量
4. Linux查看內存相關命令
① free / free -m / free -g
相關參數說明
② cat /proc/meminfo
③ jstat -gccapacity 【pid】 —— 查看堆內存使用情況,包括元空間,老年代,年輕代
- NGCMN:新生代最小容量 - NGCMX:新生代最大容量 - NGC:當前新生代容量 - S0C:第一個幸存區大小 - S1C:第二個幸存區的大小 - EC:伊甸園區的大小 - OGCMN:老年代最小容量 - OGCMX:老年代最大容量 - OGC:當前老年代大小 - OC:當前老年代大小 - MCMN:最小元數據容量 - MCMX:最大元數據容量 - MC:當前元數據空間大小 - CCSMN:最小壓縮類空間大小 - CCSMX:最大壓縮類空間大小 - CCSC:當前壓縮類空間大小 - YGC:年輕代gc次數 - FGC:老年代GC次數④ top / top 【pid】/ top -Hp【pid】
⑤ ps -aux | grep 【pid】
⑥ jmap命令
jmap -heap 【pid】 —— 查看JVM呈現堆棧使用
jmap -histo 【pid】—— 查看堆中對象數量和大小
jmap -dump:format=b,file=heapdump pid:將內存使用的詳細情況輸出到文件
⑦ jcmd 【pid】 GC.heap_dump 【輸出路徑】 —— 查看GC堆棧,同jmap -dump | jcmd [pid] VM.native_memory
⑧ watch -n 1 ps v 【pid】—— 動態查看進程內存使用,每秒刷新
⑨ strace -f -e"brk,mmap,munmap" -p 【pid】 追蹤進程內存使用
⑩ pmap -x [pid] 與 diff pmap文件1 pmap文件2 -y -w
資料:
https://elasticsearch.cn/article/178
https://my.oschina.net/alchemystar/blog/1603817
https://www.cnblogs.com/xiaohanlin/p/12888396.html
https://blog.csdn.net/hellozhxy/article/details/95203462
總結
以上是生活随笔為你收集整理的Java —— 内存泄露排查的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Sarcasm Detection wi
- 下一篇: c语言结构体嵌套及输出,C语言结构体嵌套