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

时间:2017-04-24 15:28:48

标签: java arrays garbage-collection jvm word

我已经阅读了这个问题的一些答案(Why I can't create an array with large size?https://bugs.openjdk.java.net/browse/JDK-8029587),我不理解以下内容。 "在GC代码中,我们将单词中对象的大小作为int传递。" 我知道JVM中单词的大小是4个字节。根据这一点,如果我们将大字长数组(例如,MAX_INT - 5)的大小作为int传递,我们必须得到OutOfMemoryException,其中请求的数组大小超过VM限制,因为即使没有标题大小,int的大小也太大了。那么为什么不同类型的数组对元素的最大数量有相同的限制呢?

2 个答案:

答案 0 :(得分:2)

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

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

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

考虑到需要"大"数组仍然可以创建它们;并且只有那些需要非常大的数组才会受到影响;为什么花这么努力?

答案 1 :(得分:1)

据我所知,答案在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没有指定该数组将保留的类型。)< / p>

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

 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 leasthere是一个很好的参考(我试着查看代码本身,但是有太多的引用)。