为什么我无法创建大尺寸的数组?

2022-09-04 07:00:53

为什么不可能创建具有最大int大小的数组?

int i = 2147483647;
int[] array = new int[i];

我发现这个解释:

Java 数组通过 32 位 int 进行访问,因此最大理论数组大小为 2147483647 元素。

但正如你所看到的,我的代码不起作用。也不可能创建具有大小的数组

new int[Integer.MAX_VALUE - 5];

技术细节

  • 64 位热点 JVM
  • OSX 10.10.4

附言

为什么呢?-5


答案 1

理论

有两种可能的例外情况:

  • OutOfMemoryError: Java heap space表示您的数组不适合 java 堆空间。为了解决问题,您可以使用JVM选项增加最大堆大小。还要考虑到对象的最大大小不能大于最大的堆生成-Xmx
  • OutOfMemoryError: Requested array size exceeds VM limit表示超出了特定于平台的大小:
    • 上限由用于描述数组中索引的大小类型的限制设置,因此理论数组大小受元素限制。2^31-1=2147483647
    • 另一个限制是特定于JVM/平台的。根据 Java 语言规范的第 10 章:数组,Java SE 7 版对数组长度没有严格的限制,因此可以在不违反 JLS 的情况下减小数组大小。

实践

在 HotSpot 中,JVM 数组大小受内部表示的限制。在GC代码中,JVM以堆词的形式传递数组的大小,然后从堆字转换回这可能会导致溢出。因此,为了避免崩溃和意外行为,最大数组长度受(最大大小 - 标头大小)的限制。其中头文件大小取决于 C/C++ 编译器,该编译器用于构建您正在运行的 JVM(linux 的 gcc,macos 的 clang)和运行时设置(如 )。例如在我的Linux上:intjintUseCompressedClassPointers

  • Java HotSpot(TM) 64 位服务器 VM 1.6.0_45 限制Integer.MAX_VALUE
  • Java HotSpot(TM) 64 位服务器 VM 1.7.0_72 限制Integer.MAX_VALUE-1
  • Java HotSpot(TM) 64 位服务器虚拟机 1.8.0_40 限制Integer.MAX_VALUE-2

相关链接


答案 2

某些 VM 在数组中保留一些标头词。

最大“安全”号码将be 2 147 483 639 (Integer.MAX_VALUE - 8)

源码 http://www.docjar.com/html/api/java/util/ArrayList.java.html

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

因此,这取决于现在系统上JVM可用的最大内存

编辑:为什么它显示OOM。

晶片数量 = 2 147 483 639

一个元素所需的字节数 = 4

元素总内存仅为 8589934556 KB == 8.589934555999999 GB

现在,如果数组的总内存使用率不是 8 个字节的倍数,则大小将向上舍入到下一个 8 的多字节。

因此,由于开销,您还需要比分配的更多内容,并且应该是连续内存


推荐