當寫下這行代碼時,程序會註定運行失敗。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