2017-04-24 18 views
3

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

+0

他们没有。限制是单词中的分配大小和元素数量必须符合一个带符号的32位整数。对于引用类型的数组,该大小与元素的数量相同(禁止可能的标题字)。对于字节/短,大小上限将不会被打。在32位平台上,我认为很长时间[]会被限制在axint/2项(大致)。 – Zastai

+0

在你的问题中有这个问题的答案(第一评论):https://bugs.openjdk.java.net/browse/JDK-8029587 – vhula

+1

@ Zastai如果这是真的,那么不会有任何问题,但实际上示例我无法创建MAX_INT大小为 – WildWind03

回答

2

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

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

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

并且考虑到需要“大”数组的人仍然可以创建它们;只有那些需要真的很大的阵列受到影响;为什么花了这个努力?

+0

的字节数组如果该限制是基于long类型的,那很明显。我无法理解,如果无法使用int变量索引该数组的单词,我不能理解如何创建一个长整型数组(MAX_INT - 1)。 – WildWind03

+0

我不得不承认在写回答时我很忙。如果您当时没有收到更好的输入,我可能会在明天更新它。 – GhostCat

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未指定该数组将保存哪些类型)。

现在,真正验证了最大的数组大小的方法是这样的:

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是一个很好的参考(我试图把它看成代码本身,但有太多的参考)。

+0

为什么HeapWordSize至少需要8个字节?我在这里找到http://hg.openjdk.java.net/jdk6/jdk6/hotspot/file/tip/src/share/vm/utilities/globalDefinitions.hpp MaxHeapSize = sizeof(HeapWord)和HeapWord类只有一个字段char *类型。这意味着HeapWordSize的大小取决于体系结构,也可能是4个字节。 – WildWind03

+1

@Wild_Wind你是对的,我不是。在这一点上,我有同样的斗争低估,你做。 – Eugene

相关问题