DEV Community

Truman
Truman

Posted on

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 的内存分配策略。
    • 线程优化
      • 避免多余线程的创建,进一步优化线程栈的内存分配。

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

Image of AssemblyAI

Automatic Speech Recognition with AssemblyAI

Experience near-human accuracy, low-latency performance, and advanced Speech AI capabilities with AssemblyAI's Speech-to-Text API. Sign up today and get $50 in API credit. No credit card required.

Try the API

Top comments (0)

Image of AssemblyAI

Automatic Speech Recognition with AssemblyAI

Experience near-human accuracy, low-latency performance, and advanced Speech AI capabilities with AssemblyAI's Speech-to-Text API. Sign up today and get $50 in API credit. No credit card required.

Try the API

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay