站长之家查询工具,wordpress链接微信,网站制作网页设计,做网站卖什么条件Native Memory Tracking (NMT) 是Hotspot VM用来分析VM内部内存使用情况的一个功能。我们可以利用jcmd(jdk自带)这个工具来访问NMT的数据。NMT介绍工欲善其事必先利其器#xff0c;我们先把相关需要的配置和工具介绍清楚#xff0c;再通过例子来看看具体如何使用NMT。打开NMT…Native Memory Tracking (NMT) 是Hotspot VM用来分析VM内部内存使用情况的一个功能。我们可以利用jcmd(jdk自带)这个工具来访问NMT的数据。NMT介绍工欲善其事必先利其器我们先把相关需要的配置和工具介绍清楚再通过例子来看看具体如何使用NMT。打开NMTNMT必须先通过VM启动参数中打开不过要注意的是打开NMT会带来5%-10%的性能损耗。-XX:NativeMemoryTracking[off | summary | detail]# off: 默认关闭# summary: 只统计各个分类的内存使用情况.# detail: Collect memory usage by individual call sites.jcmd查看NMT报告通过jcmd查看NMT报告以及查看对比情况。jcmd VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale KB | MB | GB]# summary: 分类内存使用情况.# detail: 详细内存使用情况除了summary信息之外还包含了虚拟内存使用情况。# baseline: 创建内存使用快照方便和后面做对比# summary.diff: 和上一次baseline的summary对比# detail.diff: 和上一次baseline的detail对比# shutdown: 关闭NMTVM退出时打印NMT可以通过下面VM参数在JVM退出时打印NMT报告。-XX:UnlockDiagnosticVMOptions -XX:PrintNMTStatisticsNMT实战症状某个服务(C)在客户环境使用后发现其内存占用不断变大且远超Xmx指定的大小导致整个系统因缺少内存造成其他服务无法启动。当时查看到其RSS大约为11G-Xmx6G而且heap利用率不到50%。userhostxxx prstat -p 2780PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP2780 user 11G 11G sleep 59 0 44:16:39 0.0% java/196userhostxxx /opt/jdk1.8.0_40/bin/jstat -gcutil 2780S0 S1 E O M CCS YGC YGCT FGC FGCT GCT0.00 100.00 90.60 46.80 98.02 97.10 11323 4049.745 11 225.345 4275.090分析服务通过-Xmx6G指定最大堆分配为6G但实际RSS已达到11G开始怀疑堆外内存是否有内存泄露。为了有更好详细的数据就在本地重现这个问题并且打开了NMT持续监控。NMT的Report如下重点关注每个分类下的commit大小这个是实际使用的内存大小。6739: #进程IDNative Memory Tracking:Total: reserved8491110KB, committed7220750KB- Java Heap (reserved6293504KB, committed6291456KB)(mmap: reserved6293504KB, committed6291456KB)- Class (reserved1107429KB, committed66189KB)(classes #11979)(malloc1509KB #18708)(mmap: reserved1105920KB, committed64680KB)- Thread (reserved159383KB, committed159383KB)(thread #156)(stack: reserved158720KB, committed158720KB)(malloc482KB #788)(arena182KB #310)- Code (reserved255862KB, committed41078KB)(malloc6262KB #9319)(mmap: reserved249600KB, committed34816KB)- GC (reserved449225KB, committed449225KB)(malloc166601KB #1714646)(mmap: reserved282624KB, committed282624KB)- Compiler (reserved395KB, committed395KB)(malloc265KB #856)(arena131KB #3)- Internal (reserved146041KB, committed146041KB)(malloc132185KB #276370)(mmap: reserved13856KB, committed13856KB)- Symbol (reserved31487KB, committed31487KB)(malloc29209KB #91080)(arena2278KB #1)- Native Memory Tracking (reserved33212KB, committed33212KB)(malloc168KB #2575)(tracking overhead33044KB)- Arena Chunk (reserved2284KB, committed2284KB)(malloc2284KB)- Unknown (reserved12288KB, committed0KB)(mmap: reserved12288KB, committed0KB)Virtual memory map:......并且在服务器上通过cron job来定期抓取NMT的report保存下来做分析而且同时也把其对应的RSS和PMAP都抓取了一份。COLLECTOR_PIDps -ef|grep ProcessName | grep -v grep | awk {print $2}OUTDIR/opt/chkmemHOSTNAMEhostnameprstat -s rss 1 1 ${OUTDIR}/${HOSTNAME}_coll_${COLLECTOR_PID}_prstat_date %Y%m%d_%H%M%S.txt/opt/jdk1.8.0_40/bin/jcmd ${COLLECTOR_PID} VM.native_memory detail ${OUTDIR}/${HOSTNAME}_coll_${COLLECTOR_PID}_nmd_date %Y%m%d_%H%M%S.txtpmap -x ${COLLECTOR_PID} ${OUTDIR}/${HOSTNAME}_coll_${COLLECTOR_PID}_pmap_date %Y%m%d_%H%M%S.txt分析发现NMT中的Symbol域持续增大从最开始的几十兆已经增加到了2G左右而且整个jvm的内存使用量也在持续增加。见下图验证后发现问题和JDK8的bug https://bugs.java.com/view_bug.do?bug_id8180048 非常类似测试后也证实确实如此最后通过升级JDK解决了这个问题。 导致这个问题的组件是Jackson Streaming API 中的 JsonFactory.Feature.INTERN_FIELD_NAMES 引起的由于项目中需要大量解析动态json文件并且key都被intern到JVM native 内存无法释放导致内存泄露。