性能问答>为什么内存中存在很多代码无关的int[]数组?>
5回复
2年前

为什么内存中存在很多代码无关的int[]数组?


环境参数
  • 操作系统Linux
  • 操作系统版本Centos7
  • JDK版本JDK8
  • 内存4GB
  • CPU核数2
  • 操作系统位数64位
33166.bin52.53MB
查看详情

各位大佬,麻烦你们帮我看看,这个大对象区域为啥这么多的 int 数组?如下图
image.png

我点进去看了很久,没有发现有任何对象引用此类对象。同时我也仔细查了代码,并没有任何地方显示创建这些数组。代码简化之后如下:

public class MemTbmkBoot {
    final static List<Method> mCache = new Vector<Method>();

    public static void main(String[] args) throws Throwable {
        final File f = new File("/Users/****/Documents/****/code/****/target/classes");
        while (true) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        ClassLoader1 classLoader1 = new ClassLoader1(new URL[]{f.toURI().toURL()});
                        ClassLoader2 classLoader2 = new ClassLoader2(new URL[]{f.toURI().toURL()});
                        ClassLoader3 classLoader3 = new ClassLoader3(new URL[]{f.toURI().toURL()});
                        final Class<?> model1Clz = classLoader1.loadClass("demo.simulators.memtbmk.TbmkModel1");
                        final Class<?> model2Clz = classLoader2.loadClass("demo.simulators.memtbmk.TbmkModel2");
                        final Class<?> model3Clz = classLoader3.loadClass("demo.simulators.memtbmk.TbmkModel3");
                        final TbmkModel1 model1 = new TbmkModel1();
                        final TbmkModel2 model2 = new TbmkModel2();
                        final TbmkModel3 model3 = new TbmkModel3();
                        for (int i = 0; i < 1000; ++i) {

                            Method m = model1Clz.getMethod("method" + i);
                            m.invoke(model1);
                            mCache.add(m);

                            m = model2Clz.getMethod("method" + i);
                            m.invoke(model2);
                            mCache.add(m);

                            m = model3Clz.getMethod("method" + i);
                            m.invoke(model3);
                            mCache.add(m);
                        }
                        System.out.println("mCache size: " + mCache.size());
                        Thread.sleep(100);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            ).start();

            Thread.sleep(100);
        }
    }
}
8729 阅读
请先登录,再评论

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

32年前
回复 十一_231439:

你可以查看一下本问题的关联文章“不起眼,但是足以让你有收获的JVM内存分析案例”,里面有比较详细的解释。

2年前回复
回复 你假笨:

那这样的话,意思是gc的时候 是多遍历了很多对象的,有没有可能填充内容太多然后回收效率就低了很多

2年前回复

e

2年前

这个问题我也看见过,求大神解答!!!!

12年前