【发布时间】:2020-12-21 06:30:30
【问题描述】:
我有一个 JAVA 进程在 64 位 LINUX 上运行,版本为“CentOS Linux release 7.3.1611”,内存为 7.6GB。
以下是一些使用的 JVM 标志,
- -Xmx3500m
- -Xms3500m
- -XX:MaxMetaspaceSize=400m
- -XX:CompressedClassSpaceSize=35m
注意:默认线程栈大小(1MB)和代码缓存(240MB),JDK版本为1.8.0_252。
在运行 TOP 命令时,它观察到我的 6.3 GB RAM 由 java 持有 过程。
PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
20 0 28.859g 6.341g 22544 S 215.2 83.1 4383:23 java
我尝试使用 JCMD、JMAP 和 JSTAT 命令分析 JVM 的本机内存。
JMAP -heap 命令的输出:
Debugger attached successfully.
Server compiler detected.
JVM version is 25.252-b14
using thread-local object allocation.
Garbage-First (G1) GC with 33 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 3670016000 (3500.0MB)
NewSize = 1363144 (1.2999954223632812MB)
MaxNewSize = 2202009600 (2100.0MB)
OldSize = 5452592 (5.1999969482421875MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 36700160 (35.0MB)
MaxMetaspaceSize = 419430400 (400.0MB)
G1HeapRegionSize = 1048576 (1.0MB)
Heap Usage:
G1 Heap:
regions = 3500
capacity = 3670016000 (3500.0MB)
used = 1735444208 (1655.048568725586MB)
free = 1934571792 (1844.951431274414MB)
47.28710196358817% used
G1 Young Generation:
Eden Space:
regions = 1311
capacity = 2193620992 (2092.0MB)
used = 1374683136 (1311.0MB)
free = 818937856 (781.0MB)
62.66730401529637% used
Survivor Space:
regions = 113
capacity = 118489088 (113.0MB)
used = 118489088 (113.0MB)
free = 0 (0.0MB)
100.0% used
G1 Old Generation:
regions = 249
capacity = 1357905920 (1295.0MB)
used = 241223408 (230.04856872558594MB)
free = 1116682512 (1064.951431274414MB)
17.76436824135799% used
485420 interned Strings occupying 83565264 bytes.
JSTAT -gc 命令的输出:
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
0.0 33792.0 0.0 33792.0 1414144.0 1204224.0 2136064.0 1558311.7 262872.0 259709.5 19200.0 18531.5 22077 985.995 10 41.789 1027.785
0.0 33792.0 0.0 33792.0 1414144.0 1265664.0 2136064.0 1558823.7 262872.0 259709.5 19200.0 18531.5 22077 985.995 10 41.789 1027.785
0.0 63488.0 0.0 63488.0 124928.0 32768.0 3395584.0 1526795.8 262872.0 259709.5 19200.0 18531.5 22078 986.041 10 41.789 1027.830
0.0 63488.0 0.0 63488.0 124928.0 49152.0 3395584.0 1526795.8 262872.0 259709.5 19200.0 18531.5 22078 986.041 10 41.789 1027.830
0.0 63488.0 0.0 63488.0 124928.0 58368.0 3395584.0 1526795.8 262872.0 259709.5 19200.0 18531.5 22078 986.041 10 41.789 1027.830
即使是 "JCMD pid VM.native_memory summary" 的输出所产生的总和也约为 5.0GB,甚至不接近 6.3GB。所以我找不到余额 1.3GB 用在哪里了。
我试图找出 6.3GB 是如何与 JVM 实际映射的。所以我决定检查 /proc/pid 文件夹。
在 /proc/pid/status 文件中,
VmRSS : 6649680 kB
RssAnon : 6627136 kB
RssFile : 22544 kB
RssShmem: 0 kB
由此我发现6.3GB的大部分空间都被匿名空间占用了。
PMAP 命令的输出(截断):
Address Kbytes RSS Dirty Mode Mapping
0000000723000000 3607296 3606076 3606076 rw--- [ anon ]
00000007ff2c0000 12544 0 0 ----- [ anon ]
00007f4584000000 132 4 4 rw--- [ anon ]
00007f4584021000 65404 0 0 ----- [ anon ]
00007f4588000000 132 12 12 rw--- [ anon ]
00007f4588021000 65404 0 0 ----- [ anon ]
00007f458c000000 132 4 4 rw--- [ anon ]
00007f458c021000 65404 0 0 ----- [ anon ]
00007f4590000000 132 4 4 rw--- [ anon ]
00007f4590021000 65404 0 0 ----- [ anon ]
00007f4594000000 132 8 8 rw--- [ anon ]
00007f4594021000 65404 0 0 ----- [ anon ]
00007f4598000000 132 4 4 rw--- [ anon ]
00007f4598021000 65404 0 0 ----- [ anon ]
00007f459c000000 2588 2528 2528 rw--- [ anon ]
我发现第一个匿名地址可能会映射到堆内存,因为它的大小为 3.4GB。但是,我无法找到其余匿名空间的使用情况。
我需要帮助找出 JVM 进程如何使用额外的 1.3 GB。
本机内存跟踪中未提及的有关 JVM 使用的内存的任何信息将不胜感激。
【问题讨论】:
-
什么代码在这个JVM上运行?尤其是您可能在通过 JNI 或类似方式与 JVM 交互的本机代码中存在泄漏。