【问题标题】:Why the maximum array size of ArrayList is Integer.MAX_VALUE - 8?为什么 ArrayList 的最大数组大小是 Integer.MAX_VALUE - 8?
【发布时间】:2016-06-15 20:10:21
【问题描述】:

我正在研究 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?

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

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

【问题讨论】:

  • 如果需要超过8个标题词,那么当它变得那么大时它会崩溃。所以 8 是 ArrayList 作者对需要的额外标题字的最大数量的估计。
  • 在一个不相关的说明中:如果你正在分配一个包含 20 亿个元素的数组,那么某处可能有问题。
  • @LouisWasserman - VM 8 字节更高?如果可能,请告诉我。
  • @SkyWalker,这句话毫无意义。此外,它是 8 个字节,而不是 8 位,这是 很多 的标题空间。
  • @LouisWasserman 我明白了。所以VM的header不会超过8个字节

标签: java arrays arraylist


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    对于热点:

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

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

    类指针32 bit 架构上具有字长。在64 bit 架构上,klass 指针要么有字长,但也可以有4 byte,如果堆地址可以编码在这些4 bytes 中。

    这种优化称为“compressed oops”,您也可以使用 UseCompressedOops 选项对其进行控制。

    What is in java object header

    【讨论】:

      【解决方案3】:

      阅读上面关于Java Memory management的文章,里面写得很清楚

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

      Java 数组对象剖析

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

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

      Lock : 对象的同步信息——也就是说, 对象当前是否同步。

      Size : 数组的大小。

      最大尺寸

      2^31 = 2,147,483,648 
      

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

      所以

      2^31 -8 (for storing size ), 
      

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

      【讨论】:

      • 对于 32 位和 64 位 java 进程,数组在这两种情况下都需要 8 个字节吗?
      • 由于对象大小被四舍五入为 8 字节的倍数,是的。
      • 不应该是Integer.MAX_VALUE - 7,因为Integer.MAX_VALUE == 2^31 - 1
      【解决方案4】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-23
        • 1970-01-01
        • 2020-03-06
        • 2023-03-08
        • 2012-11-10
        • 2011-01-07
        • 2021-11-06
        • 1970-01-01
        相关资源
        最近更新 更多