如何查看jvm堆外内存使用情况?

2 个回答

  • 松林
    入体冰凉的月光,都比不上你绝情的目光。
    ### 查看 JVM 堆外内存使用情况 JVM 的内存不仅包括堆内存,还包括很多其他部分。可以使用多种工具和方法来查看 JVM 堆外内存的使用情况,包括 JConsole、jstat、jmap 以及 Native Memory Tracking (NMT)。 #### 使用 JConsole 查看内存使用情况 JConsole 的内存页面可以显示常见的堆内存和各种堆外部分使用状态。以下是步骤: 1. 打开 JConsole 并连接到目标 JVM。 2. 在 JConsole 中,导航到“内存”页面。 3. 查看堆内存和堆外内存的使用情况。 #### 使用命令行工具 可以使用 jstat 和 jmap 等工具在运行时查询 JVM 内存的使用情况。 1. **jstat**:查看 JVM 内存使用情况的统计数据。 ```sh jstat -gc <pid> ``` 2. **jmap**:生成堆转储(Heap Dump)文件,然后利用 jhat 或 Eclipse MAT 等堆转储分析工具进行详细分析。 ```sh jmap -dump:format=b,file=heapdump.hprof <pid> ``` #### 使用 Native Memory Tracking (NMT) JDK 8 中的 Native Memory Tracking (NMT) 可以查看详细的内存使用情况。在启动参数中开启 NMT: ```sh -XX:NativeMemoryTracking=[off | summary | detail] ``` 在 JVM 退出时打印相关的统计信息: ```sh -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics ``` 在程序运行时可以使用 jcmd 查看内存的分配情况: ```sh jcmd <pid> VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB] ``` #### 输出示例 以下是使用 `jcmd` 命令查看内存分配情况的输出示例: ```sh sudo -u tomcat jcmd `pgrep -f tomcat` VM.native_memory detail 31549: Native Memory Tracking: Total: reserved=50215227KB, committed=49947839KB - Java Heap (reserved=46137344KB, committed=46137344KB) (mmap: reserved=46137344KB, committed=46137344KB) - Class (reserved=92639KB, committed=91707KB) (classes #14958) (malloc=2527KB #50184) (mmap: reserved=90112KB, committed=89180KB) - Thread (reserved=914804KB, committed=914804KB) (thread #883) (stack: reserved=906696KB, committed=906696KB) (malloc=2904KB #4435) (arena=5203KB #1764) - Code (reserved=263567KB, committed=87223KB) (malloc=13967KB #19565) (mmap: reserved=249600KB, committed=73256KB) - GC (reserved=1849937KB, committed=1849937KB) (malloc=105041KB #121050) (mmap: reserved=1744896KB, committed=1744896KB) - Compiler (reserved=13354KB, committed=13354KB) (malloc=3061KB #3484) (arena=10292KB #13) - Internal (reserved=813935KB, committed=813935KB) (malloc=813903KB #102254) (mmap: reserved=32KB, committed=32KB) - Symbol (reserved=18071KB, committed=18071KB) (malloc=14355KB #138545) (arena=3716KB #1) - Native Memory Tracking (reserved=7274KB, committed=7274KB) (malloc=298KB #4295) (tracking overhead=6976KB) - Arena Chunk (reserved=14191KB, committed=14191KB) (malloc=14191KB) - Unknown (reserved=90112KB, committed=0KB) (mmap: reserved=90112KB, committed=0KB) Virtual memory map: [0x00007ef481693000 - 0x00007ef481794000] reserved and committed 1028KB for Thread Stack from [0x00007f0486546f74] JavaThread::run()+0x24 [0x00007f04863fab88] java_start(Thread*)+0x108 [0x00007ef481794000 - 0x00007ef481895000] reserved and committed 1028KB for Thread Stack from [0x00007f0486546f74] JavaThread::run()+0x24 [0x00007f04863fab88] java_start(Thread*)+0x108 [0x00007ef48224d000 - 0x00007ef48244d000] reserved 2048KB for Class from [0x00007f0486593c66] ReservedSpace::initialize(unsigned long, unsigned long, bool, char*, unsigned long, bool)+0x256 [0x00007f0486593d0b] ReservedSpace::ReservedSpace(unsigned long, unsigned long, bool, char*, unsigned long)+0x1b [0x00007f0486379cda] VirtualSpaceNode::VirtualSpaceNode(unsigned long)+0x17a [0x00007f048637a59a] VirtualSpaceList::create_new_virtual_space(unsigned long)+0x5a [0x00007ef48228d000 - 0x00007ef4823cd000] committed 1280KB from [0x00007f0486593549] VirtualSpace::expand_by(unsigned long, bool)+0x199 [0x00007f0486377936] VirtualSpaceList::expand_node_by(VirtualSpaceNode*, unsigned long, unsigned long)+0x76 [0x00007f048637a750] VirtualSpaceList::expand_by(unsigned long, unsigned long)+0xf0 [0x00007f048637a8e3] VirtualSpaceList::get_new_chunk(unsigned long, unsigned long, unsigned long)+0xb3 [0x00007ef48224d000 - 0x00007ef48228d000] committed 256KB from [0x00007f0486593549] VirtualSpace::expand_by(unsigned long, bool)+0x199 [0x00007f0486377936] VirtualSpaceList::expand_node_by(VirtualSpaceNode*, unsigned long, unsigned long)+0x76 [0x00007f048637a8e3] VirtualSpaceList::get_new_chunk(unsigned long, unsigned long, unsigned long)+0xb3 [0x00007f048637c432] SpaceManager::grow_and_allocate(unsigned long)+0x2d2 ``` 通过这些方法,可以详细查看 JVM 堆外内存的使用情况,帮助更好地优化和管理 JVM 内存。
    编辑于 2023-12-09 16:48 •IP属地 云南
    举报
    评论
    收藏

  • 澜夜师兄
    勇敢一点吧!我们不会比今年更年轻了。
    JVM 的内存不仅包括堆内存,还包括很多其他部分。通过 Native Memory Tracking (NMT) 可以详细看到 JVM 的内存使用情况。以下是一个 NMT 输出示例及其解释。 ```java Native Memory Tracking: Total: reserved=6308603KB, committed=4822083KB - Java Heap (reserved=4194304KB, committed=4194304KB) (mmap: reserved=4194304KB, committed=4194304KB) - Class (reserved=1161041KB, committed=126673KB) (classes #21662) ( instance classes #20542, array classes #1120) (malloc=3921KB #64030) (mmap: reserved=1157120KB, committed=122752KB) ( Metadata: ) ( reserved=108544KB, committed=107520KB) ( used=105411KB) ( free=2109KB) ( waste=0KB =0.00%) ( Class space:) ( reserved=1048576KB, committed=15232KB) ( used=13918KB) ( free=1314KB) ( waste=0KB =0.00%) - Thread (reserved=355251KB, committed=86023KB) (thread #673) (stack: reserved=353372KB, committed=84144KB) (malloc=1090KB #4039) (arena=789KB #1344) - Code (reserved=252395KB, committed=69471KB) (malloc=4707KB #17917) (mmap: reserved=247688KB, committed=64764KB) - GC (reserved=199635KB, committed=199635KB) (malloc=11079KB #29639) (mmap: reserved=188556KB, committed=188556KB) - Compiler (reserved=2605KB, committed=2605KB) (malloc=2474KB #2357) (arena=131KB #5) - Internal (reserved=3643KB, committed=3643KB) (malloc=3611KB #8683) (mmap: reserved=32KB, committed=32KB) - Other (reserved=67891KB, committed=67891KB) (malloc=67891KB #2859) - Symbol (reserved=26220KB, committed=26220KB) (malloc=22664KB #292684) (arena=3556KB #1) - Native Memory Tracking (reserved=7616KB, committed=7616KB) (malloc=585KB #8238) (tracking overhead=7031KB) - Arena Chunk (reserved=10911KB, committed=10911KB) (malloc=10911KB) - Tracing (reserved=25937KB, committed=25937KB) (malloc=25937KB #8666) - Logging (reserved=5KB, committed=5KB) (malloc=5KB #196) - Arguments (reserved=18KB, committed=18KB) (malloc=18KB #486) - Module (reserved=532KB, committed=532KB) (malloc=532KB #3579) - Synchronizer (reserved=591KB, committed=591KB) (malloc=591KB #4777) - Safepoint (reserved=8KB, committed=8KB) (mmap: reserved=8KB, committed=8KB) ``` ### 解释 1. **Java Heap**: 堆内存,即 `-Xmx` 限制的最大堆大小的内存。 2. **Class**: 加载的类与方法信息,包含两部分: - Metadata,被 `-XX:MaxMetaspaceSize` 限制最大大小。 - Class space,被 `-XX:CompressedClassSpaceSize` 限制最大大小。 3. **Thread**: 线程与线程栈占用内存,每个线程栈占用大小受 `-Xss` 限制。 4. **Code**: JIT 即时编译后(C1 C2 编译器优化)的代码占用内存,受 `-XX:ReservedCodeCacheSize` 限制。 5. **GC**: 垃圾回收占用内存,例如垃圾回收需要的 CardTable,标记数,区域划分记录等。 6. **Compiler**: C1 C2 编译器本身的代码和标记占用的内存。 7. **Internal**: 命令行解析,JVMTI 使用的内存。 8. **Symbol**: 常量池占用的大小,字符串常量池受 `-XX:StringTableSize` 个数限制。 9. **Native Memory Tracking**: 内存采集本身占用的内存大小。 10. **Arena Chunk**: 通过 arena 方式分配的内存。 11. **Tracing**: 所有采集占用的内存,例如开启 JFR 时的内存占用。 12. **Logging、Arguments、Module、Synchronizer、Safepoint、Other**: 一般不需要特别关心。 ### 其他 JVM 内存 除了 Native Memory Tracking 记录的内存使用,还有两种内存 Native Memory Tracking 没有记录: 1. **Direct Buffer**: 直接内存 2. **MMap Buffer**: 文件映射内存 这两个都可以通过 Java MBean 看到。 ![Java MBean](https://images.codewd.com/4296e34950de2e2771a062f1e064c9e4.jpg) ### 总结 通过 Native Memory Tracking 可以详细了解 JVM 各个部分的内存使用情况。除了堆内存,还有很多其他内存区域需要关注。对于未记录的 Direct Buffer 和 MMap Buffer,可以通过 Java MBean 查看。了解这些有助于更好地优化和管理 JVM 内存。
    编辑于 2023-11-10 09:26 •IP属地 天津
    举报
    评论
    收藏