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

时间:2016-03-02 19:23:02

标签: java arrays arraylist

我正在研究ArrayList的Java 8文档。我得到的最大数组大小定义为Integer.MAX_VALUE - 8表示2 ^ 31 - 8 = 2 147 483 639 。然后我专注于为什么减去8或减去why 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. Do Java arrays have a maximum size?
  2. How many data a list can hold at the maximum
  3. Why I can't create an array with large size?
  4. 根据文档"Some VMs reserve some header words in an array",有些人给出了一些逻辑。因此对于标题字,减去8。但在这种情况下,如果标题词需要超过8,那么答案是什么?

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

4 个答案:

答案 0 :(得分:8)

阅读上面有关Java Memory management的文章,其中明确说明了

我认为这适用于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

答案 1 :(得分:5)

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

对于HotSpot:

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

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

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

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

What is in java object header

答案 2 :(得分:3)

该值是最糟糕的情况。请注意评论:

  

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

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

您可能需要查看此问题的答案以获取更多信息:
Why I can't create an array with large size?

答案 3 :(得分:0)

整数最大大小为: 2^31 - 1 = 2,147,483,648 - 1

Integer.java: @Native public static final int MAX_VALUE = 0x7fffffff;