jvm |nmt

Native Memory Tracking 参数解释

truman_999999999

Truman

Posted on November 19, 2024

Native Memory Tracking 参数解释

此片仅为NMT的输出信息解释,详细内容在这里

启动命令:
-Xms8G -Xmx8G -Xmn4G -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:NativeMemoryTracking=summary -XX:+UseParallelGC

输出信息:

sh-4.4# jcmd 1 VM.native_memory summary
1:

Native Memory Tracking:

(Omitting categories weighting less than 1KB)

Total: reserved=9488872KB, committed=9037604KB
       malloc: 90692KB #530181
       mmap:   reserved=9398180KB, committed=8946912KB

-                 Java Heap (reserved=8388608KB, committed=8388608KB)
                            (mmap: reserved=8388608KB, committed=8388608KB)

-                     Class (reserved=216083KB, committed=19475KB)
                            (classes #24831)
                            (  instance classes #23390, array classes #1441)
                            (malloc=3091KB #81714)
                            (mmap: reserved=212992KB, committed=16384KB)
                            (  Metadata:   )
                            (    reserved=131072KB, committed=126208KB)
                            (    used=125492KB)
                            (    waste=716KB =0.57%)
                            (  Class space:)
                            (    reserved=212992KB, committed=16384KB)
                            (    used=15382KB)
                            (    waste=1002KB =6.12%)

-                    Thread (reserved=97958KB, committed=10654KB)
                            (thread #96)
                            (stack: reserved=97644KB, committed=10340KB)
                            (malloc=205KB #579)
                            (arena=109KB #188)

-                      Code (reserved=254760KB, committed=95700KB)
                            (malloc=7072KB #22671)
                            (mmap: reserved=247688KB, committed=88628KB)

-                        GC (reserved=310290KB, committed=310286KB)
                            (malloc=6542KB #99)
                            (mmap: reserved=303748KB, committed=303744KB)

-                  Compiler (reserved=821KB, committed=821KB)
                            (malloc=657KB #1513)
                            (arena=164KB #4)

-                  Internal (reserved=1608KB, committed=1608KB)
                            (malloc=1572KB #53569)
                            (mmap: reserved=36KB, committed=36KB)

-                     Other (reserved=16890KB, committed=16890KB)
                            (malloc=16890KB #52)

-                    Symbol (reserved=41301KB, committed=41301KB)
                            (malloc=36179KB #334650)
                            (arena=5122KB #1)

-    Native Memory Tracking (reserved=8483KB, committed=8483KB)
                            (malloc=199KB #3578)
                            (tracking overhead=8284KB)

-        Shared class space (reserved=16384KB, committed=12956KB, readonly=0KB)
                            (mmap: reserved=16384KB, committed=12956KB)

-               Arena Chunk (reserved=692KB, committed=692KB)
                            (malloc=692KB #373)

-                    Module (reserved=252KB, committed=252KB)
                            (malloc=252KB #4553)

-                 Safepoint (reserved=8KB, committed=8KB)
                            (mmap: reserved=8KB, committed=8KB)

-           Synchronization (reserved=2592KB, committed=2592KB)
                            (malloc=2592KB #25509)

-            Serviceability (reserved=18KB, committed=18KB)
                            (malloc=18KB #36)

-                 Metaspace (reserved=132121KB, committed=127257KB)
                            (malloc=1049KB #1245)
                            (mmap: reserved=131072KB, committed=126208KB)

-      String Deduplication (reserved=1KB, committed=1KB)
                            (malloc=1KB #8)

-           Object Monitors (reserved=4KB, committed=4KB)
                            (malloc=4KB #19)
Enter fullscreen mode Exit fullscreen mode

JVM Native Memory Tracking (NMT) 解读

jcmd VM.native_memory summary 输出中分析 JVM 各部分内存使用情况:


1. JVM 内存总览

  • 总内存

    • reserved=9488872KB (~9GB):JVM 已保留的虚拟内存。
    • committed=9037604KB (~8.6GB):JVM 已向操作系统申请并实际使用的物理内存。
  • 分配方式

    • malloc=90692KB:通过 C 的 malloc 分配的内存。
    • mmap=9398180KB:通过内存映射(mmap)分配的内存。

2. Java 堆(Java Heap)

  • 堆内存使用

    • reserved=8388608KB (~8GB):最大堆大小。
    • committed=8388608KB (~8GB):已使用堆内存。
    • 堆内存占用了 JVM 的绝大部分内存。
  • 特点

    • 堆内存完全被 mmap 分配。
    • 堆内存未出现碎片或不足问题。

3. Class(类加载器内存)

  • 总内存

    • reserved=216083KB (~211MB):已保留。
    • committed=19475KB (~19MB):实际使用。
    • 其中,malloc 使用了 3091KB,mmap 使用了 16384KB。
  • 元空间(Metadata)

    • reserved=131072KB (~128MB):最大元空间大小。
    • committed=126208KB (~123MB):已使用。
    • used=125492KB (~122.5MB):元空间中的实际数据。
    • 元空间碎片率:0.57%。
  • Class Space(类空间)

    • reserved=212992KB (~208MB)。
    • committed=16384KB (~16MB)。
    • 使用碎片率为 6.12%。

4. 线程(Thread)

  • 线程总内存

    • reserved=97958KB (~95.6MB):保留的线程相关内存。
    • committed=10654KB (~10.4MB):实际使用的线程相关内存。
    • 当前线程数:96。
  • 栈内存(Stack)

    • reserved=97644KB (~95.3MB):线程栈的总保留内存。
    • committed=10340KB (~10.1MB):已实际分配的栈内存。
    • 每个线程的栈大小
    平均栈大小 = committed / thread count = 10340KB / 96 ≈ 107.7KB
    

5. GC(垃圾回收器)

  • GC 内存使用

    • reserved=310290KB (~303MB)。
    • committed=310286KB (~303MB)。
  • 分配方式

    • malloc=6542KB (~6.4MB)。
    • mmap=303748KB (~296.7MB)。
  • GC 内存分布

    • 主要分布在 mmap 中,可能用于 Parallel GC 的内部数据结构,如标记和回收的任务队列。

6. Code(代码缓存)

  • 代码缓存

    • reserved=254760KB (~248MB)。
    • committed=95700KB (~93MB)。
  • 特点

    • 代码缓存用于存储 JIT 编译后的方法字节码。
    • 其中 malloc=7072KBmmap=247688KB

7. Metaspace(元空间)

  • 总内存
    • reserved=132121KB (~129MB)。
    • committed=127257KB (~124MB)。
    • 实际使用
    • 元数据区使用 used=125492KB
    • 类加载空间使用 used=15382KB

8. Thread 栈空间的最大使用

  • 线程栈使用
    • 当前线程数:96。
    • 每个线程的平均实际栈使用量约为 107.7KB
    • 系统为每个线程预留了约 1MB 的栈内存空间。

总结

  1. Java 堆内存:堆内存占用 8GB,无碎片,运行正常。
  2. 线程栈使用
    • 每个线程的平均实际栈使用量约为 107.7KB
    • 系统为每个线程预留了约 1MB 的栈内存空间。
  3. 元空间(Metaspace)
    • 使用了 124MB,运行正常。
  4. 代码缓存(Code Cache)
    • JIT 编译代码占用约 93MB。

如果线程栈需要更多内存,但未超出 -Xss 限制,则分配成功;如果超出限制,会触发 StackOverflowError。当前设置下,线程运行正常,没有栈不足问题。

内存增加后命令:
-Xms10G -Xmx10G -Xmn4G -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:NativeMemoryTracking=summary -XX:+UseParallelGC

Kubernetes 监控发现使用内存 11.86GB。
输出信息:

sh-4.4# jcmd 1 VM.native_memory summary
1:

Native Memory Tracking:

(Omitting categories weighting less than 1KB)

Total: reserved=11658171KB, committed=11214347KB
       malloc: 91023KB #533380
       mmap:   reserved=11567148KB, committed=11123324KB

-                 Java Heap (reserved=10485760KB, committed=10485760KB)
                            (mmap: reserved=10485760KB, committed=10485760KB)

-                     Class (reserved=216153KB, committed=19609KB)
                            (classes #24834)
                            (  instance classes #23386, array classes #1448)
                            (malloc=3161KB #83460)
                            (mmap: reserved=212992KB, committed=16448KB)
                            (  Metadata:   )
                            (    reserved=131072KB, committed=126656KB)
                            (    used=125974KB)
                            (    waste=682KB =0.54%)
                            (  Class space:)
                            (    reserved=212992KB, committed=16448KB)
                            (    used=15385KB)
                            (    waste=1063KB =6.46%)

-                    Thread (reserved=91770KB, committed=9978KB)
                            (thread #90)
                            (stack: reserved=91476KB, committed=9684KB)
                            (malloc=192KB #543)
                            (arena=102KB #176)

-                      Code (reserved=255553KB, committed=97913KB)
                            (malloc=7865KB #23483)
                            (mmap: reserved=247688KB, committed=90048KB)

-                        GC (reserved=388402KB, committed=388398KB)
                            (malloc=6670KB #99)
                            (mmap: reserved=381732KB, committed=381728KB)

-                  Compiler (reserved=739KB, committed=739KB)
                            (malloc=575KB #1481)
                            (arena=164KB #4)

-                  Internal (reserved=1612KB, committed=1612KB)
                            (malloc=1576KB #54081)
                            (mmap: reserved=36KB, committed=36KB)

-                     Other (reserved=16849KB, committed=16849KB)
                            (malloc=16849KB #48)

-                    Symbol (reserved=41308KB, committed=41308KB)
                            (malloc=36186KB #334762)
                            (arena=5122KB #1)

-    Native Memory Tracking (reserved=8535KB, committed=8535KB)
                            (malloc=201KB #3621)
                            (tracking overhead=8334KB)

-        Shared class space (reserved=16384KB, committed=12956KB, readonly=0KB)
                            (mmap: reserved=16384KB, committed=12956KB)

-               Arena Chunk (reserved=69KB, committed=69KB)
                            (malloc=69KB #336)

-                    Module (reserved=252KB, committed=252KB)
                            (malloc=252KB #4553)

-                 Safepoint (reserved=8KB, committed=8KB)
                            (mmap: reserved=8KB, committed=8KB)

-           Synchronization (reserved=2597KB, committed=2597KB)
                            (malloc=2597KB #25558)

-            Serviceability (reserved=18KB, committed=18KB)
                            (malloc=18KB #36)

-                 Metaspace (reserved=132158KB, committed=127742KB)
                            (malloc=1086KB #1281)
                            (mmap: reserved=131072KB, committed=126656KB)

-      String Deduplication (reserved=1KB, committed=1KB)
                            (malloc=1KB #8)

-           Object Monitors (reserved=3KB, committed=3KB)
                            (malloc=3KB #17)
Enter fullscreen mode Exit fullscreen mode

JVM 内存对比分析(去除堆内存增加后的差异)

通过两次 jcmd VM.native_memory summary 输出,去除新增的 2GB 堆内存后,分析其他内存占用部分的变化。


1. 总内存

类别 第一次 (单位: KB) 第二次 (单位: KB) 差值 (单位: KB)
Reserved 9488872 (~9.0GB) 11658171 (~11.1GB) +2179299 (~2GB)
Committed 9037604 (~8.6GB) 11214347 (~10.7GB) +2176743 (~2GB)

分析

  • 增长的 2GB 是堆内存的直接增加。
  • 去除堆内存后,其他部分的变化如下。

2. 堆内存(Heap Memory)

类别 第一次 (单位: KB) 第二次 (单位: KB) 差值 (单位: KB)
Reserved 8388608 (~8GB) 10485760 (~10GB) +2097152 (~2GB)
Committed 8388608 (~8GB) 10485760 (~10GB) +2097152 (~2GB)

分析

  • 堆内存完全按照配置变化,增加了 2GB
  • 去除堆内存影响后,以下部分差异进一步分析。

3. 元空间和类加载器内存

类别 第一次 (单位: KB) 第二次 (单位: KB) 差值 (单位: KB)
Reserved 216083 (~211MB) 216153 (~211MB) +70 (~0MB)
Committed 19475 (~19MB) 19609 (~19MB) +134 (~0MB)
Metadata Used 125492 (~122MB) 125974 (~123MB) +482 (~0MB)

分析

  • 元空间使用量增加了约 0.5MB,主要因类加载数量增加(从 24831 个增加到 24834 个)。
  • 增幅很小,属于正常的运行时类加载行为。

4. 线程(Thread Memory)

类别 第一次 (单位: KB) 第二次 (单位: KB) 差值 (单位: KB)
Reserved 97958 (~95MB) 91770 (~89MB) -6188 (~6MB)
Committed 10654 (~10MB) 9978 (~9.7MB) -676 (~0.6MB)
线程数 96 90 -6

分析

  • 线程数量从 96 减少到 90,线程栈内存减少约 6MB
  • 单个线程栈平均大小保持不变,约为 107KB

5. GC 内存(Garbage Collector Memory)

类别 第一次 (单位: KB) 第二次 (单位: KB) 差值 (单位: KB)
Reserved 310290 (~303MB) 388402 (~379MB) +78112 (~76MB)
Committed 310286 (~303MB) 388398 (~379MB) +78112 (~76MB)

分析

  • GC 内存增加了 76MB,可能是更大的堆导致 GC 数据结构(如标记表和任务队列)扩展。
  • 属于垃圾回收器调整后的正常行为。

6. 代码缓存(Code Cache)

类别 第一次 (单位: KB) 第二次 (单位: KB) 差值 (单位: KB)
Reserved 254760 (~248MB) 255553 (~249MB) +793 (~0.7MB)
Committed 95700 (~93MB) 97913 (~96MB) +2213 (~2MB)

分析

  • 代码缓存增加了约 2MB,与 JIT 编译的新代码有关。
  • 增幅较小,对整体内存影响可以忽略。

7. Native Memory Tracking (NMT)

类别 第一次 (单位: KB) 第二次 (单位: KB) 差值 (单位: KB)
Reserved 8483 (~8MB) 8535 (~8MB) +52 (~0MB)
Committed 8483 (~8MB) 8535 (~8MB) +52 (~0MB)

分析

  • Native Memory Tracking 使用量略有增加,但变化非常小,仅为 52KB

8. 其他部分

类别 第一次 (单位: KB) 第二次 (单位: KB) 差值 (单位: KB)
Other 16890 (~16MB) 16849 (~16MB) -41 (~0MB)
Symbol 41301 (~40MB) 41308 (~40MB) +7 (~0MB)
Metaspace 132121 (~129MB) 132158 (~129MB) +37 (~0MB)

分析

  • 这些部分的变化非常小,可以忽略。

整体对比总结

去除新增的堆内存后,其余部分内存的变化情况如下:

  1. GC 内存

    • 增加了约 76MB,主要与更大的堆导致 GC 数据结构扩展有关。
  2. 线程内存

    • 减少了约 6MB,线程数量减少了 6 个
  3. 元空间和类加载器

    • 增加了约 0.5MB,与加载更多类(增加 4 个类)有关。
  4. 代码缓存

    • 增加了约 2MB,与 JIT 编译的新代码有关。
  5. Native Memory Tracking 和其他部分

    • 增加或减少幅度极小,影响可以忽略。

关键结论

  1. 主要变化来源

    • GC 内存 是增长的主要来源(+76MB)。
    • 线程栈内存 减少了约 6MB
  2. 总体变化幅度较小

    • 去除堆内存的增加后,整体的额外内存变化约为 +70MB,属于正常的运行时动态调整。
  3. 优化方向

    • GC 内存优化
      • 如果需要降低 GC 开销,可以使用 G1GC 或调整 GC 的内存分配策略。
    • 线程优化
      • 避免多余线程的创建,进一步优化线程栈的内存分配。

总的来说,堆外内存的变化幅度很小,对应用整体内存影响有限。

💖 💪 🙅 🚩
truman_999999999
Truman

Posted on November 19, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related