在java中,是否有可能出现OutOfMemoryError异常,即使应该有足够的内存,垃圾收集是否会释放更多内存?换句话说,如果没有足够的内存来分配,在抛出OutOfMemoryError之前是否会强制gc运行?
谢谢。
在java中,是否有可能出现OutOfMemoryError异常,即使应该有足够的内存,垃圾收集是否会释放更多内存?换句话说,如果没有足够的内存来分配,在抛出OutOfMemoryError之前是否会强制gc运行?
谢谢。
有 一 在这种情况下,您可能会获得一个既不与堆相关也不与地址空间相关的OOM:它是在JVM决定GC运行时间过长的时候。
看到 这里。
换句话说,原始问题的答案,即“如果没有足够的内存来分配,将在抛出OutOfMemoryError之前强制执行gc”,是的。
(你会从上面的链接看到gc /运行代码的比例是98%/ 2%,这是 非常 已经高了)
(注2:这是针对Sun的/ Oracle的JVM,不知道其他实现)
你可以得到它,如果GC花费太多时间试图释放内存而不是通过这样做来释放大量内存'java.lang.OutOfMemoryError:超出GC开销限制',请参阅 这个问题。
在抛出OutOfMemoryError之前,GC被强制运行。如果JVM实现了多种GC(例如“并发”或“部分”),那么“停止世界”GC将在JVM放弃之前运行,因此已尽一切努力避免错误。
引用的例外情况是,如果GC重复运行并且只能恢复极少量的存储(并且堆大小无法进一步扩展),那么它将丢弃,而不是继续以“爬行”模式运行。从理论上讲,对于这种情况,稍微增加堆大小将允许“好”应用程序运行正常,但是一个慢慢咀嚼堆的应用程序(这并不罕见)不会从轻微的堆增加中受益,并且会遇到同样的失败只是稍晚一点。
[应该注意的是,在GC运行过于频繁的情况下,增加堆大小可能会显着降低GC开销, 如果 应用程序运行良好,恰巧恰好在堆限制附近运行。 (当然,将堆大小增加到大于可用RAM通常会使应用程序运行得更慢。)]
似乎如果你编写适当的代码,你永远不会打到OOM。因为JVM会在命中OOM之前运行gc。
因此,如果你点击OOM,很可能你的代码有一些内存泄漏。 检查一下。
GC 将 一般以前尝试寻找记忆 OutOfMemoryError
扔了,但是 很偶然 我已经看到了可重现的例子,其中垃圾收集器没有完全跟上,并且调用了 System.gc()
防止异常。
这是非常例外(没有双关语意图)而不是规则 - 你应该差不多 决不 试着自己挑起垃圾收集。