Java ã§é
åãçæããéã«ãã©ãã¾ã§å¤§ããè¦ç´ æ°ãæå®ã§ãããã¯ãJava VMã®å®è£
ã«ããã¿ããã§ãã
ãªã®ã§ãOracle ã® Java VM ã§ã¯ã¡ã¢ãªãååã«ãã£ã¦ããæ¬¡ã®ã³ã¼ãã¯å¿
ãã¨ã©ã¼ã«ãªãã¾ãã
int[] max = new int[Integer.MAX_VALUE];
ããããã¡ã¢ãªãååã«ããå ´åã®ä¸éãã©ãã¾ã§ãªã®ãã¨ããã¨ãOracle ã® Java VM ã®å ´åã¯ä»¥ä¸ã®éãã§ã*1ã
32bit ã® Java VM | 0x3fffffff - 3 (= 1,073,741,820) |
64bit ã® Java VM | 0x7fffffff - 2 (= 2,147,483,645) |
ã©ããããã¨ï¼
ã¾ãã¯ãJava è¨èªä»æ§ã確èªããã¨ããã以ä¸ã®è¨è¼ãããã¾ããã
é å㯠int å¤ã«ãã£ã¦ã¤ã³ããã¯ã¹ã¥ããããªããã°ãªãããshort, byte, char å¤ãåæ°ã®æ°å¤æ ¼ä¸ãã«ãã£ã¦ int å¤ã¨ãªããããã¤ã³ããã¯ã¹å¤ã¨ãã¦ä½¿ç¨ãããã¨ãã§ããã
10.4 配列へのアクセス - Java 言語仕様 第3版
ï¼ä¸ç¥ï¼
é åã«å¯¾ãããã¹ã¦ã®ã¢ã¯ã»ã¹ã¯å®è¡æã«ãã§ãã¯ãããã¼ãããå°ããããããã¯é åã®é·ã以ä¸ã®ã¤ã³ããã¯ã¹ã使ç¨ãããã¨ããå ´åãArrayIndexOutOfBoundsException ãã¹ãã¼ãããã
è¦ããã«ãé
åã®ã¤ã³ããã¯ã¹ã«ã¯ 0 ã Integer_MAX_VALUE (=0x7fffffff) ã¾ã§ä½¿ç¨ã§ãããã¨ã®ãã¨ã§ãã
ã©ãã¾ã§çæã§ãããã«ã¤ãã¦ã¯ãå¥ã®åæ*2ã«ããï¼ã¡ã¢ãªã確ä¿ã§ããªããªãï¼ OutOfMemoryError ãã¹ãã¼ããããã¨ããè¨è¼ãããã ãã§ãã
ãã®ãã¨ãããä¸è¦ããã¨ã¡ã¢ãªãååã«ããã°è¦ç´ æ°ã Integer.MAX_VALUE ã®é
åã¾ã§çæã§ããããªæ°ããã¾ãããããã§ã¯ãªãããã§ãã
å®éã«ãã£ã¦ã¿ãã¨ãOracle ã® Java VM ã ã¨ãVMã®å¶éãè¶
ãã¦ãããã¨ããã¨ã©ã¼ã«ãªãã¾ãã
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
ã¡ã¢ãªä¸è¶³ã§ããã°ãjava.lang.OutOfMemoryError: Java heap spaceãã§ãããããã¨ã¯éãã¨ã©ã¼ã§ãã
Java VM ã®ã³ã¼ãã§ç¢ºèª
Java VMのコードをダウンロードãã¦ãä¸è¨ã®ã¡ãã»ã¼ã¸ã§ GREP ãã¦ã¿ã¾ããã
ããã¨è¦ã¤ãã£ãã®ã¯ãããªã³ã¼ãã
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()); }
arrayOopDesc::max_array_length 颿°ãããã® OutOfMemoryError ã®çºçæ¡ä»¶ã®ããã§ãã
ãã®é¢æ°ãä½ãã¨ããã¨â¦ã
// 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; }
ãããããã¾ããï¼
ãã ãHeapWordSize ã 32bit 㨠64bit ã§éã*3ã®ã§ã 32bit 㨠64bit ã®VMã§æåãéãã¯ããã¨ããã®ã¯ãããã¾ããã
ã¨ãããã¨ã§ãåé ã«æ¸ããçµæã«ãªãããã§ãã