Java陣列的長度到底能有多大
阿新 • • 發佈:2019-01-28
在確保記憶體大小的前提下,使用Oracle的Java VM,以下程式碼肯定會報錯:
Java程式碼- int[] max = newint[Integer.MAX_VALUE];
錯誤資訊是:
引用 java.lang.OutOfMemoryError: Requested array size exceeds VM limit
注意這裡的錯誤資訊不是“java.lang.OutOfMemoryError: Java heap space”,意思是申請的陣列大小已經超過堆大小。詳細參考官方說明:http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/memleaks.html#gbyvi
從https://jdk7.java.net/source.html下載Java VM原始碼 openjdk-7u40-fcs-src-b43-26_aug_2013.zip
\openjdk\hotspot\src\share\vm\oops\arrayKlass.cpp(150):
C++程式碼
- objArrayOop arrayKlass::allocate_arrayArray(int n, int length, TRAPS) {
- if (length < 0) {
- THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
- }
- if (length > arrayOopDesc::max_array_length(T_ARRAY)) {
- report_java_out_of_memory("Requested array size exceeds VM limit");
- JvmtiExport::post_array_size_exhausted();
- THROW_OOP_0(Universe::out_of_memory_error_array_size());
- }
- // ......
- }
\openjdk\hotspot\src\share\vm\oops\arrayOop.hpp(109):
C++程式碼
- // Return the maximum length of an array of BasicType. The length can passed
- // to typeArrayOop::object_size(scale, length, header_size) without causing an
- // overflow. We also need to make sure that this will not overflow a size_t on
- // 32 bit platforms when we convert it to a byte size.
- static int32_t max_array_length(BasicType type) {
- assert(type >= 0 && type < T_CONFLICT, "wrong type");
- assert(type2aelembytes(type) != 0, "wrong type");
- constsize_t max_element_words_per_size_t =
- align_size_down((SIZE_MAX/HeapWordSize - header_size(type)), MinObjAlignment);
- constsize_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;
- }
\openjdk\jdk\src\share\native\common\sizecalc.h(41):
C++程式碼
- #include <stdint.h> /* SIZE_MAX for C99+ */
- /* http://stackoverflow.com/questions/3472311/what-is-a-portable-method-to-find-the-maximum-value-of-size-t */
- #ifndef SIZE_MAX
- #define SIZE_MAX ((size_t)-1)
- #endif
32位系統中size_t是4位元組的,在64位系統中,size_t是8位元組的。
Java 7 Update 40(Windows)測試結果是:
引用 32bit的Java VM: 0x3fffffff - 3 (= 1,073,741,820)
64bit的Java VM: 0x7fffffff - 2 (= 2,147,483,645)