【问题标题】:Garbage collection before OutOfMemoryErrorOutOfMemoryError 之前的垃圾收集
【发布时间】:2012-01-19 05:28:48
【问题描述】:

这是一个关于 java 中垃圾收集的问题:如果分配了一大块内存(使用 new int[BIG_NUMBER] 或然而),是否有任何保证垃圾收集器会在抛出 OutOfMemoryError 之前收集垃圾?这是行为吗 垃圾收集器现在是 Java 规范的一部分吗?

我了解到垃圾收集器本身可能会抛出这样的异常,以防收集垃圾需要很长时间,至少在 Sun Hotspot Java 虚拟机的情况下

«如果在垃圾收集上花费的时间过多,并行/并发收集器将抛出 OutOfMemoryError:如果超过 98% 的总时间花在垃圾收集上,而回收的堆少于 2%,则OutOfMemoryError 将被抛出。此功能旨在防止应用程序长时间运行,而由于堆太小而几乎没有进展。如有必要,可以通过在命令行中添加选项 -XX:-UseGCOverheadLimit 来禁用此功能。 »

但是根据引用,这可以通过在命令中添加一个选项来禁用 行。

【问题讨论】:

  • “是否有任何保证垃圾收集器会在抛出 OutOfMemoryError 之前收集垃圾?” 如果存在对内存块的引用,则当然不能。跨度>
  • 我没有很好地表达我的问题:问题是JVM在尝试分配大块内存时会做什么,并且看到剩余的堆空间不足:首先尝试垃圾收集,看到垃圾收集后剩余的内存仍然不足,然后引发 OutOfMemoryError,否则,依靠垃圾收集器线程足够频繁地完成其工作,立即引发 OutOfMemoryError 而不尝试先进行垃圾收集。下面的 Peter Lawrey 似乎回答了这个问题。

标签: java garbage-collection operating-system


【解决方案1】:

AFAIK,它一直是规范的一部分。

如果 VM 内存非常低,则早期的 OutOfMemoryError 是 Java 6 的一项功能,引入该功能是为了在 VM 变得不可用但还没有完全死机时停止它。

我不会关闭这个功能,你最好设计你的系统,这样你就永远不会接近 98% 的内存使用率。我建议 30% 是一个更舒适的运行水平。

来自 Javadoc for Java 1.4.2(2002 年引入)http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/OutOfMemoryError.html

当 Java 虚拟机由于内存不足而无法分配对象时引发,并且垃圾收集器无法提供更多内存。

【讨论】:

    【解决方案2】:

    很简单,不。 您的程序可能会调用 Runtime.gc() 寻求帮助。

    【讨论】:

    • 不,它会在OutOfMemoryError之前运行,并且gc()不会强制GC运行。
    • 虽然您认为 System.gc() 只是一个建议是正确的,但实际上我知道的所有 vm 实现都会在调用 System.gc() 时执行 gc。破坏者会在非工作时间进行明确的 gc,以在后果较小时强制执行完整的 gc。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 2018-12-30
    相关资源
    最近更新 更多