JVM 是否保证在抛出 OutOfMemoryError 之前运行 GC?
除非 JVM 尝试完全垃圾回收,否则永远不会抛出 [
OutOfMemoryError
] 首先,包括删除软/弱引用的对象。
至于这段代码,
//.. allocate reserved memory
try {
//.. calculation which requires alot of memory even after optimized
} catch (java.lang.OutOfMemoryError e){
System.gc();
//.. hedge recovery
}
对System.gc()
的调用是多余的吗?
是否已经保证 JVM(根据JVMS )在抛出 java.lang.OutOfMemoryError
?
This thread, and this page:
It [
OutOfMemoryError
] will never be thrown unless the JVM tries a full garbage collection
first, including removal of softly/weakly referenced objects.
As for this piece of code,
//.. allocate reserved memory
try {
//.. calculation which requires alot of memory even after optimized
} catch (java.lang.OutOfMemoryError e){
System.gc();
//.. hedge recovery
}
Is the call to System.gc()
redundant?
Is it already guaranteed that JVMs (according to JVMS) had run the GC before throwing java.lang.OutOfMemoryError
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您永远不应该尝试通过运行 System.gc() 从 OutOfMemoryError 中恢复。无论是否严格保证,您都可以在JLS找到。但这从头到尾都是一个坏主意 - JVM 将尽最大努力来满足您的内存分配需求。当它放弃并抛出 OOM 时,游戏就结束了。减少内存使用量或增加堆大小,然后重试。
为了更直接地回答您的问题,捕获 OutOfMemoryError 并不意味着 GC 已经运行。例如,
可能不会调用 GC。显然这是一个荒谬的例子。我最近看到的一个更现实的情况是 OOME,其原因是“无法分配新的本机线程”。运行 GC 可能无法解决这种情况,因为 JVM 还留有堆空间,但系统不允许它有更多线程。
You should never try to recover from an OutOfMemoryError by running System.gc(). Whether or not it's strictly guaranteed, you can probably find in the JLS. But it's pretty much a bad idea through and through - the JVM will try its hardest to fulfill your memory allocation desires. When it gives up and tosses an OOM, the game is up. Either reduce your memory usage or increase the heap size, and then try again.
To more directly answer your question, catching an OutOfMemoryError does not mean GC has run. For example
will probably not invoke a GC. Obviously this is an absurd example. A more realistic one that I saw recently was an OOME with the cause "Could not allocate new native thread". Running GC would likely not resolve that sort of situation, as the JVM has heap space left but the system will not allow it more threads.
来自此处:
因此,GC 无法释放更多内存后,会抛出 OutOfMemoryException。
From here:
So, OutOfMemoryException is thrown after GC cannot free more memory.
OutOfMemoryError 有几种不同类型。例如,如果我们由于“无法创建新的本机线程”而获得 OOME,那么它不一定是由于 GC 调用所致。与“请求的数组大小超出 VM 限制”相同 - 那么我们将分配大于 VM 大小的数组,不需要调用 GC。 JVM 正在尽力做到最好,抛出 OOME 并不意味着它很快就会死掉。另外,由于“超出 GC 开销限制”而调用 System.gc() 来处理 OOME 根本没有任何意义 - 它会使情况变得更糟。
There are few different types of OutOfMemoryError. If we for example get OOME due to "Unable to create new native thread" then it's not necessarily due to GC invocation. The same with "Requested array size exceeds VM limit" - then we're going to allocate array larger than VM size calling GC is not needed. JVM is trying to do it's best and throwing OOME doesn't mean that it'll die soon. Also calling System.gc() for OOME caused by "GC overhead limit exceeded" makes no sense at all - it'll make the situation even worse.