一次java內(nèi)存top res高排查記錄
前言
分享一個最近的問題,top 看java進程res不斷升高,一天能漲3個G,使用jmap dump內(nèi)存快照后,dump下來的文件只有300多M,沒有發(fā)現(xiàn)內(nèi)存泄漏。這是個什么情況呢,我們深入分析下。
冰山一角
首先,使用top來查看下當前進程的信息

可以看到top的res占用5.3g,jvm的參數(shù)如下
早上的時候是4個g,下午的時候漲到7個g。
通過gc日志和gc次數(shù)和時間來看,fullgc并沒有有效的清理掉內(nèi)存。
我們使用jmap ?-histo:live pid
手動觸發(fā)一次fullgc,發(fā)現(xiàn)res還在持續(xù)增長,也就是說內(nèi)存肯定有泄漏的地方。
使用jmap dump出內(nèi)存,查看泄漏的地方
dump下來發(fā)現(xiàn),只有2個g,壓縮后只有300M,分析內(nèi)存中的數(shù)據(jù),并沒有泄漏的地方。
也就是說內(nèi)存泄漏的地方可能在堆外。
分析堆外內(nèi)存
NMT
NMT是Native Memory Tracking的縮寫,是Java7U40引入的HotSpot新特性,開啟后可以通過jcmd命令來對JVM內(nèi)存使用情況進行跟蹤。注意,根據(jù)Java官方文檔,開啟NMT會有5%-10%的性能損耗
添加-XX:NativeMemoryTracking=detail命令到啟動參數(shù)中,然后重啟項目。
執(zhí)行
由于我們使用的是jdk1.6,并不存在這個特性,所以只好用其他的辦法。
ps
java -XX:+PrintFlagsFinal > flags.txt 可以看到當前java 支持所有xx的命令
pmap
pmap命令是Linux上用來開進程地址空間的
執(zhí)行pmap -x?| sort -n -k3 > pmap-sorted.txt命令可以根據(jù)實際內(nèi)存排序

可以看到其他內(nèi)存塊占用的很少,最多的也只有60M,那也不可能是經(jīng)典glibc的64M問題。
smpas+gdb
由于我們的不是內(nèi)存地址段有問題,所以不dump出指定的范圍的內(nèi)存塊。如果是指定范圍的內(nèi)存塊的話,可以這么操作
??查看當前進程的所有地址
cat?/proc/pid/smaps?>?smpas.txt
查看smaps.txt,找到有問題的內(nèi)存塊地址,比如下圖中的 7fa956967000-7fa956a65000

??啟動gdb
gdb?attach?<pid>
??dump指定范圍的內(nèi)存到指定的目錄下,需要加0x
dump?memory?/tmp/0x7fa956967000-0x7fa956a65000.dump?0x7fa956967000?0x7fa956a65000
??顯示長度超過10字符的字符串
strings?-10?/tmp/0x7fa956967000-0x7fa956a65000.dump
??dump 全部內(nèi)存
由于我們這邊內(nèi)存都集中在一塊,所以自己在業(yè)務(wù)低峰期,dump下了全部內(nèi)存
??設(shè)置ulimit 查看ulimit
ulimit?-a?
為了導(dǎo)出core文件,需要先設(shè)置ulimit
core?file?size??????????(blocks,?-c)?0
data?seg?size???????????(kbytes,?-d)?unlimited
scheduling?priority?????????????(-e)?0
file?size???????????????(blocks,?-f)?unlimited
pending?signals?????????????????(-i)?31722
max?locked?memory???????(kbytes,?-l)?16384
max?memory?size?????????(kbytes,?-m)?unlimited
open?files??????????????????????(-n)?65535
pipe?size????????????(512?bytes,?-p)?8
POSIX?message?queues?????(bytes,?-q)?819200
real-time?priority??????????????(-r)?0
stack?size??????????????(kbytes,?-s)?8192
cpu?time???????????????(seconds,?-t)?unlimited
max?user?processes??????????????(-u)?31722
virtual?memory??????????(kbytes,?-v)?unlimited
file?locks??????????????????????(-x)?unlimitedulimit?-c?unlimited
??dump內(nèi)容
gcore?pid
??顯示長度超過10字符的字符串
strings?-10?core.pid?>?core.txt
查看內(nèi)容后發(fā)現(xiàn),內(nèi)存中的數(shù)據(jù)是請求和響應(yīng)的數(shù)據(jù),查看代碼后,懷疑是請求可能在某些情況下,沒有正常的關(guān)閉。

本文使用?文章同步助手?同步