Where Is the Array Length Stored in JVM? – JVM中的数组长度存储在哪里?

最后修改: 2020年 6月 30日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’re going to see how and where the HotSpot JVM stores the array length.

在这个快速教程中,我们将看到HotSpot JVM如何以及在哪里存储数组的长度。

Usually, the memory layout of run-time data areas is not part of the JVM specification and is left to the discretion of the implementor. Therefore, each JVM implementation may have a different strategy to layout objects and arrays in memory.

通常,运行时数据区域的内存布局不是 JVM 规范的一部分,而是由实现者自行决定。因此,每个JVM实现可能有不同的策略来布局内存中的对象和数组。

In this tutorial, we’re focusing on one specific JVM implementation: the HotSpot JVM. We also may use the JVM and HotSpot JVM terms interchangeably.

在本教程中,我们将专注于一个特定的JVM实现:HotSpot JVM。我们也可以交替使用JVM和HotSpot JVM的术语。

2. Dependency

2.依赖性

In order to inspect the memory layout of arrays in the JVM, we’re going to use the Java Object Layout (JOL) tool. Therefore, we need to add the  jol-core dependency:

为了检查JVM中数组的内存布局,我们要使用Java Object Layout(JOL)工具。因此,我们需要添加jol-core依赖项。

<dependency> 
    <groupId>org.openjdk.jol</groupId> 
    <artifactId>jol-core</artifactId>    
    <version>0.10</version> 
</dependency>

3. Array Length

3.阵列长度

The HotSpot JVM uses a data structure called Ordinary Object Pointers (OOPs) to represent pointers to objects. To be more specific, the HotSpot JVM represents the arrays with a special OOP called arrayOop. Each arrayOop includes an object header with the following details:

HotSpot JVM使用一种叫做普通对象指针(OOPs)的数据结构来表示对象的指针。更具体地说,HotSpot JVM用一种叫做arrayOop的特殊OOP表示数组。每个arrayOop都包括一个包含以下细节的对象头。

  • One mark word to store the identity hash code or GC information
  • One klass word to store general class metadata
  • 4 bytes representing the array length

Therefore, the JVM stores the array length in the object header.

因此,JVM将数组长度存储在对象头中

Let’s verify this by inspecting the memory layout of an array:

让我们通过检查一个数组的内存布局来验证这一点。

int[] ints = new int[42];
System.out.println(ClassLayout.parseInstance(ints).toPrintable());

As shown above, we’re parsing the memory layout from an existing array instance. Here’s how the JVM lays out the int[]:

如上所示,我们正在解析一个现有数组实例的内存布局。下面是JVM如何布局int[]的。

[I object internals:
 OFFSET  SIZE   TYPE DESCRIPTION               VALUE
      0     4        (object header)           01 00 00 00 (00000001 00000000 00000000 00000000) (1) # mark
      4     4        (object header)           00 00 00 00 (00000000 00000000 00000000 00000000) (0) # mark
      8     4        (object header)           6d 01 00 f8 (01101101 00000001 00000000 11111000) (-134217363) #klass
     12     4        (object header)           2a 00 00 00 (00101010 00000000 00000000 00000000) (42) # array length
     16   168    int [I.<elements>             N/A
Instance size: 184 bytes

As mentioned earlier, the JVM stores the array length inside the object header after mark and klass words. Also, the array length will be stored in 4 bytes, so it can’t be greater than the maximum value for a 32-bit integer.

如前所述,JVM将数组长度存储在对象头内,在mark和klass字之后。另外,数组长度将被存储在4个字节中,所以它不能大于32位整数的最大值。

After the object header, the JVM stores the actual array elements. Since we have an array of 42 integers, the total size of the array is 168 bytes — 42 multiplied by 4.

在对象头之后,JVM存储实际的数组元素。由于我们有一个42个整数的数组,数组的总大小是168字节–42乘以4。

4. Conclusion

4.总结

In this short tutorial, we saw how the JVM stores the array length.

在这个简短的教程中,我们看到了JVM如何存储数组的长度。

As usual, all the examples are available over on GitHub.

像往常一样,所有的例子都可以在GitHub上找到