Java堆不完整但仍然出错java.lang.OutOfMemoryError:Java堆空间

时间:2016-06-16 15:14:45

标签: java heap-dump

我的生产应用程序中出现了这个奇怪的问题。我检查了服务器上的堆空间,没有发现任何异常(请参见下面的屏幕),但我仍然在我的应用程序执行的一些操作中得到以下错误。有可能吗?

enter image description here

java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2271)
at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118)
at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1876)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1785)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1188)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)

我怀疑问题是代码中的列表之一,它将同时被几乎2M的记录填充,但仍然不确定为什么会发生这种情况,因为堆未显示已满或最多使用,但是仍然收到此错误。可能吗?什么是可能的场景,有没有办法防止这种情况发生。这是生产应用程序,所以我将无法共享代码。请帮帮我。

3 个答案:

答案 0 :(得分:3)

抛出OutOfMemoryError并不是完整的。它必须处于当前大小加上下一个请求分配的大小超过最大值的情况。在这里你清楚地复制了一个足够大的数组,分配它会跳闸(跳闸)这种情况。

答案 1 :(得分:0)

来自java.lang.OutOfMemoryError

  

当Java虚拟机由于内存不足而无法分配对象时抛出,垃圾收集器不再提供更多内存。 OutOfMemoryError对象可以由虚拟机构造,就像禁用抑制和/或堆栈跟踪不可写一样。

简而言之,您尝试完成的操作需要在堆上有一定量的内存(创建一个包含200万个元素的新数组将需要8-16 + MB附近的某个位置,具体取决于您的JVM实施),你的JVM说它根本没有那么多可用。你没有看到可用堆上方的内存峰值,因为JVM会在它发生之前阻止它发生。

请注意,这是一个错误而不是异常,因此为什么堆栈跟踪的javadoc都没有提及它,以及为什么没有预期处理它而不是检查异常。

答案 2 :(得分:-1)

复制数组的堆栈跟踪顶部的函数似乎是在开始复制之前检查它是否有足够的空间容纳整个数组。这可以解释为什么抛出错误时堆不会被填充。整个数组是否可以复制到堆中?