Java数组的长度到底能有多大?
程序员文章站
2022-05-01 09:40:05
...
在确保内存大小的前提下,使用Oracle的Java VM,以下代码肯定会报错:
错误信息是:
注意这里的错误信息不是“java.lang.OutOfMemoryError: Java heap space”,意思是申请的数组大小已经超过堆大小。详细参考官方说明:http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/memleaks.html#gbyvi。根据Java语言规范,数组下标可以使用0 到 Integer.MAX_VALUE (=0x7fffffff) ,可以使用不代表一定能够使用,要看OS、Java VM能生成到多大。
从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):
\openjdk\hotspot\src\share\vm\oops\arrayOop.hpp(109):
\openjdk\jdk\src\share\native\common\sizecalc.h(41):
32位系统中size_t是4字节的,在64位系统中,size_t是8字节的。
Java 7 Update 40(Windows)测试结果是:
int[] max = new int[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。根据Java语言规范,数组下标可以使用0 到 Integer.MAX_VALUE (=0x7fffffff) ,可以使用不代表一定能够使用,要看OS、Java VM能生成到多大。
从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):
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):
// 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"); 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; }
\openjdk\jdk\src\share\native\common\sizecalc.h(41):
#include <stdint.h> /* SIZE_MAX for C99+ */ /* http://*.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)
64bit的Java VM: 0x7fffffff - 2 (= 2,147,483,645)
推荐阅读
-
Java实现给定一个无序的整数数组,找到其中最长上升子序列的长度。
-
Java任意长度byte数组转换为int数组的方法
-
java 定义长度为0的数组/空数组案例
-
Java获得一个数组的指定长度排列组合算法示例
-
Java算法(递归):两个不同长度的有序数组求第k小的元素(时间复杂度为:O(log(m1 + m2)))。
-
一篇文章带你搞懂 Java 中数组长度为 0 和数组为 null 的区别
-
java获取一个int数组中最大的1的长度
-
灵魂拷问:Java如何获取数组和字符串的长度?length还是length()?
-
php向java传数组,java接收到的数组长度为0,该怎么处理
-
php向java传数组,java接收到的数组长度为0