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

Joh*_*ter 6 java jvm jvm-hotspot

为什么不可能创建一个max int size的数组?

int i = 2147483647;
int[] array = new int[i];
Run Code Online (Sandbox Code Playgroud)

我找到了这个解释:

通过32位整数访问Java数组,最大理论数组大小为2147483647个元素.

但是你可以看到我的代码不起作用.创建一个大小的数组也是不可能的

new int[Integer.MAX_VALUE - 5];
Run Code Online (Sandbox Code Playgroud)

技术细节

  • 64位HotSpot JVM
  • OSX 10.10.4

PS

为什么-5呢?

Iva*_*tov 19

理论

有两种可能的例外:

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

实践

在HotSpot JVM中,数组大小受内部表示的限制.在GC代码中,JVM在堆字中传递一个数组的大小,int然后从堆字转换回来,jint这可能会导致溢出.因此,为了避免崩溃和意外行为,最大数组长度受限于(最大大小 - 标头大小).凡头的大小依赖于C/C++编译器,用于构建正在运行的JVM(GCC为Linux,铛适用于MacOS)和运行时设置(如UseCompressedClassPointers).例如在我的linux上:

  • 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位服务器VM 1.8.0_40限制 Integer.MAX_VALUE-2

有用的链接

  • 是否有任何类型的公开 API 来查询此限制?类似 System.getMaxArraySize() 的东西? (2认同)