当写下这行代码时,程序会注定运行失败。html
String strs[] = new String[Integer.MAX_VALUE];
错误信息:java.lang.OutOfMemoryError: Requested array size exceeds VM limit.java
并且在jdk源码中总会看到相似这样的定义:web
/** * The maximum size of array to allocate. * Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in * OutOfMemoryError: Requested array size exceeds VM limit */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
看注释能够了解到,jvm会为数组头信息保留一些空间。官方给出的解释。咱们去看看jvm内部是如何实现的。数组
objArrayOop ArrayKlass::allocate_arrayArray(int n, int length, TRAPS) { //... 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()); } //... }
其中, T_ARRAY = 13,表示数据类型。oracle
enum BasicType { T_BOOLEAN = 4, T_CHAR = 5, T_FLOAT = 6, T_DOUBLE = 7, T_BYTE = 8, T_SHORT = 9, T_INT = 10, T_LONG = 11, T_OBJECT = 12, T_ARRAY = 13, T_VOID = 14, T_ADDRESS = 15, T_NARROWOOP = 16, T_METADATA = 17, T_NARROWKLASS = 18, T_CONFLICT = 19, // for stack value type with conflicting contents T_ILLEGAL = 99 };
根据数据类型,得到对象头大小jvm
// 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_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_down(max_jint - header_size(type), MinObjAlignment); } return (int32_t)max_elements_per_size_t; }
至此咱们了解到,jvm中,数组对象的头上是有一些信息的,这些信息须要占用必定的空间,因此在java中,新建数组是不能够指定其大小为Integer.MAX_VALUE。并且在内存中分配这么大的对象,在编码中也是不提倡的。oop