为什么 JVM 使用全 0 的巨型 int[]?

Why does the JVM use giant int[] of all 0's?

我知道 JVM 有一个固有的开销,我想做进一步的研究以确切了解开销是什么。

使用 YourKit 分析器,我发现有巨大的 int[] 填充了看似随机的信息。我的猜测是这些存储了一些性能指标和 JVM 用来优化应用程序的其他东西;但令我惊讶的是所有元素都是值 0.

为了得到我的结果,我使用了以下 "do nothing" 程序,因此结果只包括 JVM 上发生的事情。

public final class Main {

    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(Long.MAX_VALUE);
    }

}

这是profiling结果的截图,有需要的可以上传内存截图

您可以通过检查这些数组的传入链接找到答案。只需右键单击一个可达数组,select 'Selected Objects' 然后切换到 'Incoming References'.

我发现在sun.util.calendar.ZoneInfosun.util.Calendar.BaseCalendarjava.util.Currency

中有表格

很难确定,但最有可能的是,JVM 使用那些无法访问的大型非归零数组从 .class 文件加载 Java 字节代码。 JVM编译后不需要,所以发布了,还没有收。

我一直在研究这个问题,它肯定与堆大小有关。例如,如果我设置-Xmx5m -Xmx5m,int 数组分配就没有了。而如果我设置 -Xmx5g -Xms5g,它会创建更大的数组。

我想知道他们用它们做什么。

得到了 /r/java 的帮助。

“很可能,这些是线程本地分配缓冲区中的填充对象,有助于堆的可解析性:https://shipilev.net/jvm-anatomy-park/5-tlabs-and-heap-parsability/ 它们应该是不可访问的,并由解析堆转储的工具过滤。在您的屏幕截图中,探查器显示 "All Objects (reachable and unreachable)"."