java 进程的 RES(驻留)内存使用量无法解释地增加

问题描述 投票:0回答:1

我正在调查从 Glassfish/Java 8 移植的 Java 17 spring boot 3 应用程序中的内存问题。它在 kubernetes 上运行。

  • 容器内存请求=限制=5.5Gib。堆是 -Xms = -Xmx = 3.5Gib。
  • 容器寿命很长,并运行一个使用quartz调度程序来运行作业的java进程。

最终,containerd 在达到容器内存限制时会 oom-killing java 进程。 jconsole 中的监控显示 gc 将堆轻松保持在 3.5Gib 之内。启用 NMT(本机内存跟踪器)不会显示任何关注大小的非堆内存池。

我还使用 NMT 在运行“堆密集型”短期作业之前生成基线,然后在完成后与该基线进行比较。我还使用 jconsole 和

top
进行监控。我发现
top
报告作业执行导致java进程中RES内存永久增加;即使 jconsole 或 NMT 都没有表明任何原因。

对于 NMT 的承诺总额:

  • 作业运行前的 NMT:4.535Gib (4755595KB)。容器报告 RES 上的
    top
    。即进程驻留内存为 3.1Gib(奇怪??)
  • 作业后的 NMT 4.56Gib(4778088KB 仅增加了 22493KB)(容器顶部报告 RES 大幅增加,即常驻内存为 4.9Gib - 并且永远不会返回到较低值)

通过此作业执行使用 jconsole 显示堆使用情况很好地保持在 -Xmx 和执行其作业的常规 gc 周期内;作业结束后堆使用率恢复到正常水平。

NMT 输出:

创建预运行基线:

[root@host-1 opt]# sudo -u appuser /opt/java/openjdk/bin/jcmd 191 VM.native_memory baseline
191:
Baseline succeeded

然后发布作业生成差异:

[root@host-1 opt]# sudo -u appuser /opt/java/openjdk/bin/jcmd 191 VM.native_memory summary.diff
191:

Native Memory Tracking:

(Omitting categories weighting less than 1KB)

Total: reserved=5558072KB +11469KB, committed=4778088KB +22493KB

-                 Java Heap (reserved=3670016KB, committed=3670016KB)
                            (mmap: reserved=3670016KB, committed=3670016KB)
 
-                     Class (reserved=331083KB +223KB, committed=26571KB +543KB)
                            (classes #33968 +545)
                            (  instance classes #31813 +515, array classes #2155 +30)
                            (malloc=3403KB +223KB #83118 +5582)
                            (mmap: reserved=327680KB, committed=23168KB +320KB)
                           : (  Metadata)
                            (    reserved=196608KB, committed=161088KB +4736KB)
                            (    used=160529KB +4619KB)
                            (    waste=559KB =0.35% +117KB)
                           : (  Class space)
                            (    reserved=327680KB, committed=23168KB +320KB)
                            (    used=22637KB +321KB)
                            (    waste=531KB =2.29% -1KB)
 
-                    Thread (reserved=192733KB +9279KB, committed=20945KB +995KB)
                            (thread #0)
                            (stack: reserved=192188KB +9252KB, committed=20400KB +968KB)
                            (malloc=327KB +16KB #1128 +54)
                            (arena=218KB +11 #373 +18)
 
-                      Code (reserved=254471KB +1005KB, committed=105347KB +15257KB)
                            (malloc=6787KB +1005KB #31852 +3340)
                            (mmap: reserved=247684KB, committed=98560KB +14252KB)
 
-                        GC (reserved=243202KB +494KB, committed=128490KB +494KB)
                            (malloc=13346KB +494KB #39503 +4498)
                            (mmap: reserved=229856KB, committed=115144KB)
 
-                  Compiler (reserved=1237KB +48KB, committed=1237KB +48KB)
                            (malloc=1072KB +48KB #3239 +180)
                            (arena=165KB #5)
 
-                  Internal (reserved=7246KB +271KB, committed=7246KB +271KB)
                            (malloc=7210KB +271KB #38329 +4138)
                            (mmap: reserved=36KB, committed=36KB)
 
-                     Other (reserved=587124KB +186KB, committed=587124KB +186KB)
                            (malloc=587124KB +186KB #99 +6)
 
-                    Symbol (reserved=38580KB +343KB, committed=38580KB +343KB)
                            (malloc=36334KB +279KB #888476 +9518)
                            (arena=2246KB +64 #1)
 
-    Native Memory Tracking (reserved=17131KB +436KB, committed=17131KB +436KB)
                            (malloc=38KB +1KB #573 +12)
                            (tracking overhead=17093KB +435KB)
 
-        Shared class space (reserved=16384KB, committed=12056KB)
                            (mmap: reserved=16384KB, committed=12056KB)
 
-               Arena Chunk (reserved=479KB -991KB, committed=479KB -991KB)
                            (malloc=479KB -991KB)
 
-                   Tracing (reserved=32KB, committed=32KB)
                            (arena=32KB #1)
 
-                    Module (reserved=792KB +93KB, committed=792KB +93KB)
                            (malloc=792KB +93KB #4842 +285)
 
-                 Safepoint (reserved=8KB, committed=8KB)
                            (mmap: reserved=8KB, committed=8KB)
 
-           Synchronization (reserved=150KB +11KB, committed=150KB +11KB)
                            (malloc=150KB +11KB #1575 +105)
 
-            Serviceability (reserved=1KB, committed=1KB)
                            (malloc=1KB #12)
 
-                 Metaspace (reserved=197375KB +59KB, committed=161855KB +4795KB)
                            (malloc=767KB +59KB #558 +81)
                            (mmap: reserved=196608KB, committed=161088KB +4736KB)
 
-      String Deduplication (reserved=1KB, committed=1KB)
                            (malloc=1KB #8)
 
-           Object Monitors (reserved=29KB +13KB, committed=29KB +13KB)
                            (malloc=29KB +13KB #141 +66)
 
[root@host-1 opt]# 

字段 RES 的含义(驻留内存大小,以 KiB 为单位):代表虚拟内存空间 (VIRT) 的子集,表示任务当前使用的非交换物理内存。

这证实了我的预期,即 RES 应与 NMT 承诺总量相当接近。请注意,这篇文章是相关的,但没有回答我的问题:Difference between Resident Set Size (RSS) and Java Total Commited Memory (NMT) for a JVM running in Docker container - 似乎更表明 NMT 总提交量可能经常高于 RES - 与我所看到的相反。

我的问题是:

  1. 为什么
    top
    RES头值(4.9Gib)和java的NMT总提交量(3.5Gib)之间存在这样的差异?
  2. 我是否正确解释了 NMT/top/jconsole 的输出?
  3. 我应该使用什么工具来追踪 RES 如此高的根源,因为它似乎不是 JVM 堆大小问题; NMT 似乎表明它也不是本机内存(但这让我想知道还有什么其他内存??)
  4. 还有其他指点吗??
memory-management memory-leaks jvm containerd
1个回答
0
投票

同样的问题。

我的 pmap 显示 64MB 对,如 this ,并设置环境变量 MALLOC_ARENA_MAX=1 或切换到 jemalloc 确实解决了我的问题。

为此还存在一个 open jdk 问题

© www.soinside.com 2019 - 2024. All rights reserved.