为什么在Java中创建MAX_INT大小的数组是不可能的?

我已经阅读了这个问题的一些答案( 为什么我不能创建一个大尺寸的数组?和https://bugs.openjdk.java.net/browse/JDK-8029587 ),我不明白以下内容。 “在GC代码中,我们将单词中对象的大小作为int传递。” 据我所知,JVM中单词的大小是4个字节。 根据这一点,如果我们将大字长数组(例如,MAX_INT – 5)的大小作为int传递,我们必须得到OutOfMemoryException, 请求的数组大小超过VM限制,因为大小对于int来说太大了没有标题的大小。 那么为什么不同类型的数组对元素的最大数量有相同的限制?

只解决为什么不同类型的数组对元素的最大数量有相同的限制? 部分:

因为它在实际的现实中并不重要; 但允许实现JVM的代码更简单。

当只有一个限制时; 各种数组都是一样的; 然后你可以使用该代码处理所有数组。 而不是有很多特定类型的代码。

鉴于需要“大型”数组的人仍然可以创建它们; 只有那些需要真正大型数组的人才会受到影响; 为什么花这么努力?

据我所知,答案是在jdk来源中(我正在看jdk-9); 在写完之后我不确定它是否应该是一个评论(如果它回答了你的问题),但评论太长了……

首先从hotspot/src/share/vm/oops/arrayKlass.cpp抛出错误:

 if (length > arrayOopDesc::max_array_length(T_ARRAY)) { report_java_out_of_memory("Requested array size exceeds VM limit"); .... } 

现在, T_ARRAY实际上是BasicType类型的枚举,如下所示:

 public static final BasicType T_ARRAY = new BasicType(tArray); // tArray is an int with value = 13 

这是第一个指示,当计算最大大小时,jdk不关心该数组将保持什么( T_ARRAY不指定该数组将保持什么类型)。

现在,实际validation最大数组大小的方法如下所示:

  static int32_t max_array_length(BasicType type) { assert(type >= 0 && type < T_CONFLICT, "wrong type"); assert(type2aelembytes(type) != 0, "wrong type"); const size_t max_element_words_per_size_t = align_size_down((SIZE_MAX/HeapWordSize - header_size(type)), MinObjAlignment); const size_t max_elements_per_size_t = HeapWordSize * max_element_words_per_size_t / type2aelembytes(type); if ((size_t)max_jint < max_elements_per_size_t) { // It should be ok to return max_jint here, but parts of the code // (CollectedHeap, Klass::oop_oop_iterate(), and more) uses an int for // passing around the size (in words) of an object. So, we need to avoid // overflowing an int when we add the header. See CRs 4718400 and 7110613. return align_size_down(max_jint - header_size(type), MinObjAlignment); } return (int32_t)max_elements_per_size_t; } 

我没有过多地深入研究代码,但它基于HeapWordSize ; 8 bytes at least8 bytes at least 。 这是一个很好的参考(我试着查看代码本身,但有太多的引用)。