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

我正在研究ArrayList Java 8文档。 我得到的最大数组大小定义为Integer.MAX_VALUE - 8表示2 ^ 31 – 8 = 2 147 483 639 。 然后我专注于为什么减去8或why not less than 8或者why not less than 8 more 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. 为什么我无法创建大尺寸的数组?

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

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

阅读上面有关Java内存管理的文章,该文章明确指出

我认为这适用于ArrayList,因为它是Resizable数组实现。

Java数组对象的剖析

数组对象的形状和结构(例如int值数组)类似于标准Java对象的形状和结构。 主要区别在于数组对象有一个额外的元数据,表示数组的大小。 然后,数组对象的元数据包括:Class:指向类信息的指针,它描述对象类型。 对于int字段数组,这是一个指向int []类的指针。

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

锁定:对象的同步信息 – 即对象当前是否已同步。

大小:数组的大小。

最大尺寸

 2^31 = 2,147,483,648 

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

所以

 2^31 -8 (for storing size ), 

所以最大数组大小定义为Integer.MAX_VALUE – 8

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

对于HotSpot:

对象标题由a mark worda klass pointer

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

klass指针32 bit体系结构上具有字大小。 在64 bit体系结构中,klass指针具有字大小,但如果堆地址可以在这4 bytes编码,则也可以具有4 byte 4 bytes

此优化称为“压缩oops” ,您还可以使用选项UseCompressedOops控制它。

什么是java对象头文件

该值是最坏的情况。 注意评论:

尝试分配更大的数组可能会导致OutOfMemoryError

它不会说愿意 ,只是可能 。 如果你保持低于这个值,你应该没有问题(当然,只要内存可用)。

您可能需要查看此问题的答案以获取更多信息:
为什么我无法创建大尺寸的数组?