2017-04-24 56 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

相關問題