You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

集群内部分机器内存持续上涨触发告警的排查解决求助

集群机器内存持续上涨告警排查求助

问题背景

集群内部分机器内存持续上涨直至触发告警,已尝试多种常规排查手段但未找到根源,现提供异常机器与正常机器的对比信息,请求排查思路。

异常机器与正常机器对比信息

【异常机器】

  • top显示内存占用10GB
  • Java Native Memory Tracking(NMT)已提交9479MB:
Native Memory Tracking:

Total: reserved=10651MB, committed=9479MB
-                 Java Heap (reserved=7168MB, committed=7168MB)
                            (mmap: reserved=7168MB, committed=7168MB) 
 
-                     Class (reserved=1147MB, committed=140MB)
                            (classes #22587)
                            (malloc=3MB #50903) 
                            (mmap: reserved=1144MB, committed=137MB) 
 
-                    Thread (reserved=1020MB, committed=1020MB)
                            (thread #1013)
                            (stack: reserved=1016MB, committed=1016MB)
                            (malloc=3MB #5073) 
                            (arena=1MB #2021)
 
-                      Code (reserved=262MB, committed=112MB)
                            (malloc=18MB #26576) 
                            (mmap: reserved=244MB, committed=93MB) 
 
-                        GC (reserved=354MB, committed=354MB)
                            (malloc=56MB #58554) 
                            (mmap: reserved=298MB, committed=298MB) 
 
-                  Compiler (reserved=2MB, committed=2MB)
                            (malloc=2MB #4614) 
 
-                  Internal (reserved=649MB, committed=649MB)
                            (malloc=649MB #66342) 
 
-                    Symbol (reserved=26MB, committed=26MB)
                            (malloc=24MB #242279) 
                            (arena=2MB #1)
 
-    Native Memory Tracking (reserved=7MB, committed=7MB)
                            (tracking overhead=7MB)
 
-                   Unknown (reserved=14MB, committed=0MB)
                            (mmap: reserved=14MB, committed=0MB)

【正常机器】

  • top显示内存占用8.1GB
  • Java Native Memory Tracking(NMT)已提交9291MB:
Native Memory Tracking:

Total: reserved=10465MB, committed=9291MB
-                 Java Heap (reserved=7168MB, committed=7168MB)
                            (mmap: reserved=7168MB, committed=7168MB) 
 
-                     Class (reserved=1140MB, committed=132MB)
                            (classes #20844)
                            (malloc=4MB #50411) 
                            (mmap: reserved=1136MB, committed=128MB) 
 
-                    Thread (reserved=1087MB, committed=1087MB)
                            (thread #1079)
                            (stack: reserved=1082MB, committed=1082MB)
                            (malloc=3MB #5403) 
                            (arena=1MB #2153)
 
-                      Code (reserved=262MB, committed=110MB)
                            (malloc=18MB #25669) 
                            (mmap: reserved=244MB, committed=92MB) 
 
-                        GC (reserved=333MB, committed=333MB)
                            (malloc=35MB #38960) 
                            (mmap: reserved=298MB, committed=298MB) 
 
-                  Compiler (reserved=3MB, committed=3MB)
                            (malloc=3MB #5355) 
 
-                  Internal (reserved=427MB, committed=427MB)
                            (malloc=427MB #50809) 
 
-                    Symbol (reserved=24MB, committed=24MB)
                            (malloc=22MB #227078) 
                            (arena=2MB #1)
 
-    Native Memory Tracking (reserved=6MB, committed=6MB)
                            (tracking overhead=6MB)
 
-                   Unknown (reserved=14MB, committed=0MB)
                            (mmap: reserved=14MB, committed=0MB) 

堆内存情况对比

异常机器与正常机器堆内存占用基本一致,异常机器有3次Full GC,但未发现明显异常:

异常机器(jstat -gc 1954)

S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
 0.0   262144.0  0.0   262144.0 3637248.0 425984.0 3440640.0  2568134.1  140052.0 123958.6 18452.0 15316.6  12853  585.804   3     27.154  612.958

正常机器(jstat -gc 1973)

S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
 0.0   163840.0  0.0   163840.0 4194304.0 1605632.0 2981888.0  2257346.5  131496.0 114735.3 17356.0 14088.7  10696  336.754   0      0.000  336.754

核心矛盾

异常机器top显示内存占用10GB,正常机器为8.1GB,但NMT显示两者内存提交量差异仅约188MB,堆内存占用也基本一致,且异常机器内存仍在持续上涨。


排查思路建议

1. 深入分析NMT的Internal区域差异

异常机器Internal区域提交量比正常机器多222MB(649MB vs 427MB),且malloc次数更多。执行以下命令查看Internal区域细分:

jcmd <pid> VM.native_memory detail scale=MB

重点关注Internal下的子项,比如miscellaneous、jdk.internal.misc.Unsafe相关的内存分配,这类内存通常由直接内存、JNI调用分配的内存或JVM内部结构占用,可能存在泄漏。

2. 排查直接内存泄漏

直接内存默认属于NMT的Internal区域,若应用大量使用ByteBuffer.allocateDirect()或第三方依赖(如Netty、JDBC驱动)使用直接内存未释放,会导致内存上涨:

  • 检查应用代码中直接内存的使用逻辑,确认是否有未正确释放的场景;
  • 启用JVM参数-XX:MaxDirectMemorySize限制直接内存大小,观察是否触发OOM以定位泄漏点;
  • 使用jmap -histo:live <pid>对比两台机器的java.nio.DirectByteBuffer实例数量及占用大小。

3. 排查JNI/Native代码内存泄漏

若应用包含JNI调用或使用带Native代码的第三方库,可能存在Native内存泄漏:

  • 检查自定义JNI代码的内存分配和释放逻辑是否匹配;
  • 对比异常机器与正常机器的第三方依赖版本,排查是否存在特定版本的内存泄漏问题;
  • 使用系统级工具排查进程内存:
    • pmap -x <pid>查看进程内存映射,对比匿名内存(anon)区域大小;
    • perf工具跟踪内存分配事件,定位Native代码的内存分配热点。

4. 检查JVM参数差异

对比两台机器的JVM启动参数,重点关注:

  • 堆外内存相关参数(如-XX:MaxMetaspaceSize、-XX:MaxDirectMemorySize、-Xss);
  • GC参数差异(异常机器有Full GC,确认是否因GC策略不同导致内存释放不及时);
  • 是否开启调试或监控参数导致额外内存占用。

5. 排查系统层面内存占用

top显示的RSS(常驻内存)包含JVM未统计的内存,比如内核页表、共享内存段、未释放的内存映射文件:

  • 使用cat /proc/<pid>/smaps | grep -E '^(Size|Rss|Pss|Shared|Private)' | sort -k2 -n查看进程详细内存分布;
  • 对比两台机器的Private Dirty内存大小,此部分为进程独占的已修改内存,若异常机器数值远高于正常机器,说明存在JVM未统计到的内存泄漏。

内容的提问来源于stack exchange,提问作者keller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 11:35:54