垃圾收集器是否保证在Out of Memory Error之前运行?

时间:2012-09-06 11:06:50

标签: java memory garbage-collection jvm out-of-memory

如果堆已满,JVM会抛出一个 OutOfMemoryError。但是它确保在抛出这样的异常之前总是发生(完全)垃圾收集吗?

这意味着当抛出异常时,内存只有强引用对象(或GC Roots可以访问)才能满。

编辑:假设Sun JVM - HotSpot正在讨论中。

5 个答案:

答案 0 :(得分:21)

Java Machine Specification states in section 6.3(强调我的):

  

OutOfMemoryError:Java虚拟机实现已用完   虚拟或物理内存,自动存储管理器无法使用   回收足够的内存以满足对象创建请求。

因此,JVM确实保证它会在抛出OOME之前尝试通过垃圾收集释放内存。

答案 1 :(得分:12)

车库收集器通常会在抛出OutOfMemoryError之前运行。但是如果你

,你可能会得到一个没有GC的OOME
  • 尝试创建一个非常大的对象(例如,大于堆)
  • 启动一个线程,没有足够的虚拟内存或资源来启动线程。
  • 如果达到最大直接内存,旧版本的Java会抛出此错误。

答案 2 :(得分:7)

您无法保证已执行完整垃圾回收,但VM已尝试通过垃圾回收提供足够的内存。你可以在API documentation for the OutOfMemoryError class

中找到它
  

当Java虚拟机因内存不足而无法分配对象时抛出,垃圾收集器不再提供更多内存。

请注意,在某些情况下,垃圾收集器可以在没有实际尝试丢弃未引用的对象实例的情况下确定没有足够的内存可用。最明显的例子是,如果您尝试一次性分配更多内存(例如,大字节数组),而不是最大堆大小。在这种情况下,可能会抛出OutOfMemoryError而根本不运行垃圾收集器。

答案 3 :(得分:2)

没有保证OutOfMemoryError之前的最后一个操作是垃圾收集。很可能不是,因为垃圾收集会减少已用内存的数量而不会增加它。

答案 4 :(得分:2)

除了人们已经回答的内容之外,还有其他因素需要考虑,例如您正在使用的垃圾收集策略。考虑吞吐量垃圾收集,如果花费太多时间来收集并且没有足够的内存被释放(这可能已经改变了事情),这将引发内存不足异常。说完所有这些后我就不会假设垃圾收集发生在我正在编写的应用程序执行中的任何时候...