为什么 ArrayList 的最大数组大小是 Integer.MAX_VALUE - 8?

2022-09-03 01:34:33

我正在学习 Java 8 文档。我得到的最大数组大小被定义为意味着2 ^ 31 – 8 = 2 147 483 639。然后我专注于为什么减去或减去8?ArrayListInteger.MAX_VALUE - 8why not less than 8more than 8

/**
 * The maximum size of array to allocate.
 * Some VMs reserve some header words in an array.
 * Attempts to allocate larger arrays may result in
 * OutOfMemoryError: Requested array size exceeds VM limit
 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

我得到了一些相关的答案,但没有实现我的主旨。

  1. Java 数组是否有最大大小?
  2. 列表最多可以保存多少数据
  3. 为什么我无法创建大尺寸的数组?

有些人给出了一些逻辑,根据文档。因此,对于标题单词,将减去 8。但是在这种情况下,如果标题词需要超过8个,那么答案是什么?"Some VMs reserve some header words in an array"

请在此基础上澄清我。提前感谢您的合作。


答案 1

阅读上面关于Java内存管理的文章,其中明确指出

我认为这适用于ArrayList,因为它是可调整大小的数组实现。

Java 数组对象剖析

数组对象(如 int 值数组)的形状和结构类似于标准 Java 对象的形状和结构。主要区别在于数组对象具有表示数组大小的附加元数据。然后,数组对象的元数据由以下部分组成: 类 :指向类信息的指针,它描述了对象类型。对于 int 字段数组,这是指向 int[] 类的指针。

Flags :描述对象状态的标志的集合,包括对象的哈希代码(如果有)和对象的形状(即对象是否为数组)。

Lock :对象的同步信息,即对象当前是否已同步。

大小 :数组的大小。

最大尺寸

2^31 = 2,147,483,648 

作为数组,它需要自己存储大小8 bytes2,147,483,648

所以

2^31 -8 (for storing size ), 

因此最大数组大小定义为 Integer.MAX_VALUE - 8


答案 2

对象标头的大小不能超过 8 个字节。

对于热点:

对象标头由 和 组成。a mark worda klass pointer

标记字具有字大小(在 32 位体系结构上为 4 字节,在 64 位体系结构上为 8 字节)和

klass 指针在体系结构上具有字大小。在体系结构上,klass 指针要么具有字大小,但如果堆地址可以在这些中编码,也可以具有。32 bit64 bit4 byte4 bytes

这种优化称为“压缩的oops”,您也可以使用UseCompressedOops选项来控制它。

Java 对象标头中的内容