JVM内存分析案例:分析dump文件,发现内存中存在很多代码无关的int[]数组?

JVM知识专栏JVM-火种,持续更新,喜欢请关注 

文章转自:不起眼,但是足以让你有收获的JVM内存分析案例

一个同学在perfam社区提问:“分析dump文件,发现内存中存在很多代码无关的int[]数组?我点进去看了很久,没有发现有任何对象引用此类对象。同时我也仔细查了代码,并没有任何地方显示创建这些数组”。

JVM内存分析案例:分析dump文件,发现内存中存在很多代码无关的int[]数组?_第1张图片

分析


这个问题说白了,就是说有些int[]对象不知道是哪里来的,于是我拿他的例子跑了跑,好像还真有这么回事。点该 dump 文件详情,查看相关的 int[] 数组,点该对象的“被引用对象”,发现所有的对象都是待回收的状态,即也没有被任何对象引用,确实很蹊跷。看了他的例子确实没有任何地方有 new int[] 的地方。

柳暗花明


由于内存 dump 文件通过 jmap 获取,于是自然就开始怀疑jmap了,难道是因为jmap导致的?所以我开始check jmap的实现,包括JDK和JVM里的逻辑,我要找到哪里可能会创建int数组,JDK层面基本可以忽略,因为实在想不到会有啥逻辑可能会有int数组产生,只是发了个命令给JVM进程而已,于是我重点分析JVM层面的实现,当我们使用jmap做了一次dump的时候或者gc发生的时候都会走到下面的逻辑,代码位置:hotspot/src/share/vm/gc_interface/collectedHeap.cpp

JVM内存分析案例:分析dump文件,发现内存中存在很多代码无关的int[]数组?_第2张图片

因为GC或者内存dump,都必须对内存做一个遍历,因此必须先暂停这些Java线程,防止在遍历内存里的对象的时候进行内存分配,但是每个线程分配内存其实都是优先走tlab(每个线程独有的一块在eden里的小内存块)的,为了能快速遍历对象,而不存在不连续的内存,于是JVM会对tlab做一个填充,填充的正好是int数组对象(从上面代码得知),将剩下的没被分配的tlab内存给填满了,因此在系统运行过程中其实可能伴随着很多无用的对象产生,哈哈,看到这里你是不是豁然开朗?

你是否可以解释如下问题了?

  • 线程越多,int数组增长越快
  • 没有分配byte数组,int数组增长很慢,甚至不增长?
  • jmap其实也不是唯一的因素

JVM内存分析案例:分析dump文件,发现内存中存在很多代码无关的int[]数组?_第3张图片

 

 

你可能感兴趣的:(JVM-火种)