本文涉及以下内容开启NMT查看JVM内存使用情况
通过pmap命令查看进程物理内存使用情况
smaps查看进程内存地址
gdb命令dump内存块
背景
最近收到运维反馈,说有项目的一个节点的RSS已经是Xmx的两倍多了,因为是ECS机器所以项目可以一直运行,幸亏机器内存充足,不然就可能影响到其他应用了。
排查问题
通过跳板机登录到目标机器,执行top命令,再按c,看到对应的进程所占用的RES有8个多G(这里当时忘记截图了),但是实际上我们配置的Xmx只有3G,而且程序还是正常运行的,所以不会是堆占用了这么多,于是就把问题方向指向了非堆的内存。
首先想到通过Arthas查看内存分布情况,执行dashboard命令,查看内存分布情况
发现堆和非堆的内存加起来也就2个G不到,但是这里看到的非堆只包含了code_cache和metaspace的部分,那有没有可能是其他非堆的部分有问题呢?
NMTNMT是Native Memory Tracking的缩写,是Java7U40引入的HotSpot新特性,开启后可以通过jcmd命令来对JVM内存使用情况进行跟踪。注意,根据Java官方文档,开启NMT会有5%-10%的性能损耗。-XX:NativeMemoryTracking=[off | summary | detail]