2009-12-10 58 views
3

在DKSRathore的问题中How to simulate the Out Of memory : Requested array size exceeds VM limit创建阵列时出现了一些奇怪的现象。尝试创建不同大小的阵列时Java OutOfMemoryError消息发生更改

创建大小为Integer.MAX_VALUE的数组时,抛出了一个异常,并且出现了错误java.lang.OutOfMemoryError Requested array size exceeds VM limit

但是,如果创建的数组大小小于最大值但仍在虚拟机内存上限,则会将错误消息读取为java.lang.OutOfMemoryError: Java heap space

进一步测试我设法缩小了错误消息更改的位置。

long[] l = new long[2147483645]; 

例外信息读取“请求的阵列大小超过VM限制”

long[] l = new long[2147483644]; 

例外信息读取“Java堆空间错误”

我增加了我的虚拟机的内存,并且仍然产生的相同的结果。

有没有人知道为什么会发生这种情况?

一些额外的信息:

Integer.MAX_VALUE = 2147483647 

编辑:这是我用来查找值的代码,可能会有所帮助:

int max = Integer.MAX_VALUE; 
boolean done = false; 
while (!done) { 
    try { 
     max--; 
     // Throws an error 
     long[] l = new long[max]; 
     // Exit if an error is no longer thrown 
     done = true; 
    } catch (OutOfMemoryError e) { 
     if (!e.getMessage().contains("Requested array size exceeds VM limit")) { 
      System.out.println("Message changes at " + max); 
      done = true; 
     } 
    } 
} 
+0

该死的你......现在我正在寻找找出原因!奇数(MAX_VALUE - 3) – TofuBeer 2009-12-10 15:24:58

+0

我试图为此找到一个这里的龙标签! – Gordon 2009-12-10 16:23:46

+0

你传入了什么VM参数?只有-Xms和-Xmx? – 2009-12-10 16:47:07

回答

6

望着JDK 7的源代码:

退房代码here

if (length > arrayOopDesc::max_array_length(T_ARRAY)) { 
    THROW_OOP_0(Universe::out_of_memory_error_array_size()); 
} 

然后,你可以看到一个神奇的数字来自通过查看max_array_lengthhere定义。

static int32_t max_array_length(BasicType type) { 
    assert(type >= 0 && type < T_CONFLICT, "wrong type"); 
    assert(type2aelembytes[type] != 0, "wrong type"); 
    // We use max_jint, since object_size is internally represented by an 'int' 
    // This gives us an upper bound of max_jint words for the size of the oop. 
    int32_t max_words = (max_jint - header_size(type) - 2); 
    int elembytes = (type == T_OBJECT) ? T_OBJECT_aelem_bytes : type2aelembytes[type]; 
    jlong len = ((jlong)max_words * HeapWordSize)/elembytes; 
    return (len > max_jint) ? max_jint : (int32_t)len; 
} 

所以幻数是INT最大 - 报头大小的数组 - 2.我想这意味着对于这种特殊类型的header_size是一个,给予幻数MAX_VALUE -3

1

也许有适宜的规模在全球的Java限制的数组,无论可用的堆空间是什么?

0

玩了这个之后,我认为AndreaG可能是对的。语言设计师可能选择了一个相对较高的数字,因为极限思维“没有人在他们的正确思维中需要这么大的数组”。

1

如所提到的here

3.1.3详细消息:请求的阵列大小超过限制VM

详细消息请求阵列 大小超过VM LIMI t指示 该应用程序(或该应用程序使用的API)试图分配大于堆 大小的 阵列。例如,如果应用程序 尝试分配512MB的数组,但最大堆大小为256MB,则将抛出OutOfMemoryError ,原因是请求的数组大小为 超过VM限制。在大多数情况下 问题或者是配置 问题(堆大小太小),或导致应用程序 试图创建一个巨大的数组,用于 例如一个错误 ,当阵列中的元素 的数目是使用计算不正确的 大小的 算法计算。

这导致您的heapsize只适合大小为2147483644的数组,但不完全自由导致第二个消息的结论。在第一条消息中分配比heapsize更多的结果。

相关问题