java -XX:NativeMemoryTracking=summary -jar app.jar jcmd 21455 VM.native_memory summary scale=MB jcmd 21455 VM.native_memory baseline jcmd 21455 VM.native_memory summary.diff scale=MB
容器内存 4.8G,堆稳定在 2G,GC 正常,jcmd VM.native_memory summary 里 Internal 从 300MB 涨到 1.6G,Other 还有 800MB。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。
追下去是这么回事:堆外内存分布在元空间、线程栈、直接缓冲和 JIT 代码缓存,默认不统计就只剩 RSS 一个数字。NMT 需要启动时开启,运行中打开只能看到基线之后的部分。
「堆外内存统计」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。同一份配置存在多处的,先确认改的是被加载的那一份。
新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。
接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。
处理上按这个顺序:启动参数加 -XX:NativeMemoryTracking=summary;用 jcmd VM.native_memory summary 对比两个时间点;对增长最快的分类查对应组件 线程数或 ByteBuf;需要细节时再开 detail 模式 注意有 5% 左右开销。
确认没问题再收工,能指出增长的具体分类 RSS 与 NMT 各项之和的差值控制在 10% 以内。
