我們有一個運行在Mule上的java應用程序。我們爲6144M配置了XMX值,但通常會看到整個內存使用率攀升和攀升。在我們主動重新啓動它之前,前一天接近20 GB。如何調試JVM上本機內存中的泄漏?
Thu Jun 30 03:05:57 CDT 2016
top - 03:05:58 up 149 days, 6:19, 0 users, load average: 0.04, 0.04, 0.00
Tasks: 164 total, 1 running, 163 sleeping, 0 stopped, 0 zombie
Cpu(s): 4.2%us, 1.7%sy, 0.0%ni, 93.9%id, 0.2%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 24600552k total, 21654876k used, 2945676k free, 440828k buffers
Swap: 2097144k total, 84256k used, 2012888k free, 1047316k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3840 myuser 20 0 23.9g 18g 53m S 0.0 79.9 375:30.02 java
的JPS命令顯示:
10671 Jps
3840 MuleContainerBootstrap
的jstat命令顯示:
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
37376.0 36864.0 16160.0 0.0 2022912.0 1941418.4 4194304.0 445432.2 78336.0 66776.7 232 7.044 17 17.403 24.447
啓動自變量(敏感位改變):
3840 MuleContainerBootstrap -Dmule.home=/mule -Dmule.base=/mule -Djava.net.preferIPv4Stack=TRUE -XX:MaxPermSize=256m -Djava.endorsed.dirs=/mule/lib/endorsed -XX:+HeapDumpOnOutOfMemoryError -Dmyapp.lib.path=/datalake/app/ext_lib/ -DTARGET_ENV=prod -Djava.library.path=/opt/mapr/lib -DksPass=mypass -DsecretKey=aeskey -DencryptMode=AES -Dkeystore=/mule/myStore -DkeystoreInstance=JCEKS -Djava.security.auth.login.config=/opt/mapr/conf/mapr.login.conf -Dmule.mmc.bind.port=1521 -Xms6144m -Xmx6144m -Djava.library.path=%LD_LIBRARY_PATH%:/mule/lib/boot -Dwrapper.key=a_guid -Dwrapper.port=32000 -Dwrapper.jvm.port.min=31000 -Dwrapper.jvm.port.max=31999 -Dwrapper.disable_console_input=TRUE -Dwrapper.pid=10744 -Dwrapper.version=3.5.19-st -Dwrapper.native_library=wrapper -Dwrapper.arch=x86 -Dwrapper.service=TRUE -Dwrapper.cpu.timeout=10 -Dwrapper.jvmid=1 -Dwrapper.lang.domain=wrapper -Dwrapper.lang.folder=../lang
添加「容量」項目從jps顯示只有我的6144m被用於java堆。哪裏是剩下的內存正在使用?堆棧內存?本地堆?我甚至不知道如何繼續。
如果讓它繼續增長,它會佔用系統上的所有內存,並且最終會看到系統凍結導致交換空間錯誤。
我有另一個開始增長的過程。目前約有11g的常駐記憶。
pmap 10746 > pmap_10746.txt
cat pmap_10746.txt | grep anon | cut -c18-25 | sort -h | uniq -c | sort -rn | less
Top 10 entries by count:
119 12K
112 1016K
56 4K
38 131072K
20 65532K
15 131068K
14 65536K
10 132K
8 65404K
7 128K
Top 10 entries by allocation size:
1 6291456K
1 205816K
1 155648K
38 131072K
15 131068K
1 108772K
1 71680K
14 65536K
20 65532K
1 65512K
And top 10 by total size:
Count Size Aggregate
1 6291456K 6291456K
38 131072K 4980736K
15 131068K 1966020K
20 65532K 1310640K
14 65536K 917504K
8 65404K 523232K
1 205816K 205816K
1 155648K 155648K
112 1016K 113792K
這似乎是在告訴我,因爲XMX和XMX被設置爲相同的值,有6291456K爲Java堆單分配。其他分配不是Java堆內存。他們是什麼?他們正在分配相當大的塊。
不是一個正確的答案,但是我在網絡緩衝區中發生過這種情況。顯然,如果你訂閱了多播並且不讀取它(或者緩慢讀取它),入站緩衝區可以增長到很大的大小(我已經觀察到了10的GB)。也許這對其他網絡來說是真的。我還沒有找到有效分析進程內存轉儲的方法,不幸的是,即使是粗略的視圖(並且對實際的答案會很感興趣)。 – Ordous
檢查直接ByteBuffer內存(可通過MXBean'java.nio:type = BufferPool'獲得)。試試[Native Memory Tracking](https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html)功能。 – apangin
我仍在運行Java 7,所以它看起來像本機內存跟蹤不是我的選擇。雖然看起來非常有用。 – Galuvian