JVM通常会额外分配内存。这些额外的分配,会导致java程序占用的内存,超出-Xmx的限制。让我们使用NMT查看内存的使用情况

NMT 是什么

NMT 是一种 Java Hotspot VM 功能,用于跟踪 HotSpot VM 的内部内存使用情况。您可以使用该jcmd实用程序访问 NMT 数据。NMT 不跟踪第三方本机代码和 Oracle Java Development Kit (JDK) 类库的内存分配。NMT 不包括MBeanHotSpot for Java Mission Control (JMC) 中的 NMT。

主要特征

Native Memory Tracking 与 jcmd一起使用时,可以在不同级别跟踪 Java 虚拟机 (JVM) 或 HotSpot VM 内存使用情况。NMT 仅跟踪 JVM 或 HotSpot VM 使用的内存,而不是用户的本机内存。NMT 没有提供类数据共享 (CDS) 存档使用的内存的完整信息。

NMT 支持以下功能:

  • 生成摘要和详细报告。

  • 为以后的比较建立早期基线。(基线是在特定时期的一个“快照”。)

  • 使用 JVM 命令行选项在 JVM 退出时请求内存使用报告。

使用

HotSpot VM 的 NMT 默认关闭。

启用 NMT

语法:

-XX:NativeMemoryTracking=[off | summary | detail]

参数说明:

NMT 选项 描述
off

NMT默认关闭。

summary

仅收集子系统聚合的内存使用情况。

detail

收集各个调用站点的内存使用情况。

 java -XX:NativeMemoryTracking=detail -jar test.jar

注:启用 NMT 会导致 5% -10% 的性能开销。

未开启NMT,提示:

Native memory tracking is not enabled

[root@sanxingtongxue ~]# jcmd 513791 VM.native_memory
513791:
Native memory tracking is not enabled

使用 jcmd 访问 NMT 数据

jcmd收集转储数据,并可选择将数据与上一个基线进行比较。

语法:

jcmd <pid> VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB]

参数说明:

jcmd NMT 选项 描述
summary

打印按类别汇总的摘要。

detail
  • 打印内存使用情况,按类别汇总
  • 打印虚拟内存映射
  • 打印内存使用情况,按调用站点汇总
baseline

创建一个新的内存使用快照进行比较。

summary.diff

根据最后一个基线打印一份新的总结报告。

detail.diff

根据最后一个基线打印一份新的详细报告。

shutdown

停止 NMT。

示例如下:

[root@sanxingtongxue ~]# jcmd 523265 VM.native_memory summary
523265:Native Memory Tracking:Total: reserved=1830732KB, committed=145464KB
-                 Java Heap (reserved=442368KB, committed=44060KB)(mmap: reserved=442368KB, committed=44060KB) -                     Class (reserved=1082480KB, committed=36464KB)(classes #6162)(malloc=1136KB #6847) (mmap: reserved=1081344KB, committed=35328KB) -                    Thread (reserved=29927KB, committed=29927KB)(thread #30)(stack: reserved=29792KB, committed=29792KB)(malloc=102KB #174) (arena=32KB #56)-                      Code (reserved=251447KB, committed=11795KB)(malloc=1847KB #3272) (mmap: reserved=249600KB, committed=9948KB) -                        GC (reserved=1473KB, committed=181KB)(malloc=25KB #126) (mmap: reserved=1448KB, committed=156KB) -                  Compiler (reserved=151KB, committed=151KB)(malloc=18KB #308) (arena=133KB #5)-                  Internal (reserved=11357KB, committed=11357KB)(malloc=11325KB #7724) (mmap: reserved=32KB, committed=32KB) -                    Symbol (reserved=9890KB, committed=9890KB)(malloc=6813KB #60966) (arena=3077KB #1)-    Native Memory Tracking (reserved=1463KB, committed=1463KB)(malloc=180KB #2549) (tracking overhead=1283KB)-               Arena Chunk (reserved=177KB, committed=177KB)(malloc=177KB)

结果参数说明:

Total Allocations

NMT显示总的预留内存、已提交内存:

Total: reserved=1830732KB, committed=145464KB

预留内存表示我们的应用程序可能使用的内存总量。已提交内存表示应用程序当前使用的内存。

Java Heap

heap内存占用情况显示如下:

  Java Heap (reserved=442368KB, committed=44060KB)(mmap: reserved=442368KB, committed=44060KB)

Thread

线程内存分配情况如下:

Thread (reserved=29927KB, committed=29927KB)(thread #30)(stack: reserved=29792KB, committed=29792KB)(malloc=102KB #174) (arena=32KB #56)

30个线程,stack内存共计29M,差不多每个线程的stack占用1M。JVM在创建线程时,同时分配stack内存,所以预留内存和提交内存是一样的。

Code Cache

JIT生成并缓存的汇编指令的内存占用情况:

Code (reserved=251447KB, committed=11795KB)(malloc=1847KB #3272) (mmap: reserved=249600KB, committed=9948KB)

GC

GC内存占用情况如下:

 GC (reserved=1473KB, committed=181KB)(malloc=25KB #126) (mmap: reserved=1448KB, committed=156KB)

Serial GC是一个简单的多的方法,当使用此方法时,配置方法如下:

java -XX:NativeMemoryTracking=summary -Xms300m -Xmx300m -XX:+UseSerialGC -jar test.jar

当然,我们不能仅根据内存消耗来决定选择什么GC算法,因为Serial GC的“stop-the-world”特性,可能会导致性能下降。

Symbol

symbol内存占用情况如下,如string table和constant pool:

Symbol (reserved=9890KB, committed=9890KB)(malloc=6813KB #60966) (arena=3077KB #1)

大概占用9M。

在 VM 退出时获取 NMT 数据

要在 VM 退出时获取上次内存使用情况的数据,请在启用本机内存跟踪时使用以下 VM 诊断命令行选项。详细程度基于跟踪级别。

-XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics

使用 NMT 检测内存泄漏

使用本机内存跟踪检测内存泄漏的过程。
请按照以下步骤检测内存泄漏:

  1. 使用命令行选项启动 JVM 并进行摘要或详细信息-XX:NativeMemoryTracking=summary跟踪:-XX:NativeMemoryTracking=detail.
  2. 建立早期基线。使用 NMT 基线功能通过运行以下命令在开发和维护期间获取要比较的基线:jcmd <pid> VM.native_memory baseline.
  3. 使用以下方法监视内存更改:jcmd <pid> VM.native_memory detail.diff
  4. 如果应用程序泄漏少量内存,则可能需要一段时间才能显示出来。

示例如下:

$ jcmd <pid> VM.native_memory baseline
Baseline succeeded

然后,过一段时间,可以将当前内存占用与基线做比较:

$ jcmd <pid> VM.native_memory summary.diff

NMT通过+ -符号,表示这段时间内,内存占用的变化情况:

[root@sanxingtongxue ~]# jcmd 523265 VM.native_memory summary.diff
523265:Native Memory Tracking:Total: reserved=1831059KB +359KB, committed=146815KB +1383KB-                 Java Heap (reserved=442368KB, committed=44060KB)(mmap: reserved=442368KB, committed=44060KB)-                     Class (reserved=1082518KB +38KB, committed=37526KB +1062KB)(classes #6372 +210)(malloc=1174KB +38KB #7083 +236)(mmap: reserved=1081344KB, committed=36352KB +1024KB)-                    Thread (reserved=29927KB, committed=29927KB)(thread #30)(stack: reserved=29792KB, committed=29792KB)(malloc=102KB #174)(arena=32KB #56)-                      Code (reserved=251480KB +34KB, committed=11828KB +34KB)(malloc=1880KB +34KB #3409 +137)(mmap: reserved=249600KB, committed=9948KB)-                        GC (reserved=1473KB, committed=181KB)(malloc=25KB #126)(mmap: reserved=1448KB, committed=156KB)-                  Compiler (reserved=161KB +10KB, committed=161KB +10KB)(malloc=28KB +10KB #334 +26)(arena=133KB #5)-                  Internal (reserved=11398KB +41KB, committed=11398KB +41KB)(malloc=11366KB +41KB #7936 +212)(mmap: reserved=32KB, committed=32KB)-                    Symbol (reserved=10046KB +156KB, committed=10046KB +156KB)(malloc=6969KB +156KB #62913 +1947)(arena=3077KB #1)-    Native Memory Tracking (reserved=1511KB +81KB, committed=1511KB +81KB)(malloc=187KB +33KB #2645 +469)(tracking overhead=1325KB +47KB)-               Arena Chunk (reserved=177KB, committed=177KB)(malloc=177KB)


三四更雪风不减吹袭一夜

Java本机内存跟踪NMT实战详解相关推荐

  1. Qt 零基础设计实现TCP服务器和客户端上位机(零基础实战详解,附源码文件)

    文章目录 TCP和UDP TCP的三次握手和四次分手 TCP和UDP的区别 关于Socket(套接字) Qt TCP服务器的设计与实现 使用Qt的 帮助 TCP服务器和客户端 区别 UI界面设计和原则 ...

  2. java 内存跟踪_详解JVM中的本机内存跟踪

    1.概述 有没有想过为什么Java应用程序通过众所周知的-Xms和-Xmx调优标志消耗的内存比指定数量多得多?出于各种原因和可能的优化,JVM可以分配额外的本机内存.这些额外的分配最终会使消耗的内存超 ...

  3. 《Java和Android开发实战详解》——1.2节Java基础知识

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第1章,第1.2节Java基础知识,作者 陈会安,更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

  4. java内存 海子_Java虚拟机:JVM内存模型和volatile详解

    JVM内存模型和volatile详解 Java内存模型 随着计算机的CPU的飞速发展,CPU的运算能力已经远远超出了从主内存(运行内存)中读取的数据的能力,为了解决这个问题,CPU厂商设计出了CPU内 ...

  5. 《Java和Android开发实战详解》——2.5节良好的Java程序代码编写风格

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第2章,第2.5节良好的Java程序代码编写风格,作者 陈会安,更多章节内容可以访问云栖社区"异步社区&quo ...

  6. 《Java和Android开发实战详解》——2.2节构建Java应用程序

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第2章,第2.2节构建Java应用程序,作者 陈会安,更多章节内容可以访问云栖社区"异步社区"公众号 ...

  7. 第10课:底实战详解使用Java开发Spark程序学习笔记

    第10课:底实战详解使用Java开发Spark程序学习笔记 本期内容: 1. 为什么要使用Java? 2. 使用Java开发Spark实战 3. 使用Java开发Spark的Local和Cluster ...

  8. php java内存占用_PHP内存溢出优化代码详解

    相信很多人做大批量数据导出和数据导入的时候,经常会遇到PHP内存溢出的问题,在解决了问题之后,总结了一些经验,整理成文章记录下. 优化点 1.优化SQL语句,避免慢查询,合理的建立索引,查询指定的字段 ...

  9. 基于Java的音频转发服务器_javaCV开发详解之5:录制音频(录制麦克风)到本地文件/流媒体服务器(基于javax.sound、javaCV-FFMPEG)...

    javaCV系列文章: 补充篇: 前言:本篇文章基于javaCV-FFMPEG,关于javaCV官方是没有文档或者api文档可以参考的,所以还有很多地方需要研究: 本章对于ffmpeg的需要有一定了解 ...

最新文章

  1. 你的vs.net 2005过期了吗?
  2. 多核处理器_手机处理器性能排行:骁龙865第四,麒麟9000拿下第二
  3. Centos7 Java8的安装
  4. swagger api文档_带有Swagger的Spring Rest API –创建文档
  5. java学习(66):局部类内方法访问
  6. LeetCode 第 29 场双周赛(890/2259,前39.4%)
  7. HTML/CSS开发规范指南
  8. 使用IDEA创建Maven项目教程
  9. c# printDialog不显示问题
  10. 【系统分析师之路】系统分析师冲刺习题集(数学与经济管理)
  11. 怎么在win7上安装AIR780E的USB驱动
  12. 生成国庆头像网站的源码及搭建教程
  13. 优盘格式化后如何免费恢复
  14. appid 原始id_微信开发之小程序登录相关的各类ID
  15. c语言速算24课程设计,C语言速算24数据结构课程设计.doc
  16. [解决方法] 连接深信服Easyconnect之后无法代理抓包
  17. 上海住房公积金账号系统及查询
  18. BLDC四大方案(转)
  19. SpringBoot知识点整理
  20. php函数名命名规范,PHP语言的命名规则

热门文章

  1. 六种电脑快捷键操作让你的效率比以前更高
  2. 迭代次数表达的宇称不守恒现象
  3. 【校招】面试_字节跳动_客户端开发工程师_二面
  4. oracle分页查询中的page,用简单的例子解释Oracle分页查询
  5. 听云server探针安装历程
  6. 常用正则表达式爬取网页信息及HTML分析总结
  7. C语言编码图书借阅系统
  8. K8S---Helm
  9. CAD圆命令的高阶练习、CAD高阶绘图练习
  10. 嵌入式硬件入门——74HC245三态收发器(方向可控,提供驱动)