JVM是否可以保证在抛出OutOfMemoryError之前运行GC?

Pac*_*ier 3 java garbage-collection jvm

这个帖子,和这个页面:

OutOfMemoryError除非JVM首先尝试完整的垃圾收集,否则永远不会抛出它,包括删除轻微/弱引用的对象.

至于这段代码,

//.. allocate reserved memory
try {
    //.. calculation which requires alot of memory even after optimized
} catch (java.lang.OutOfMemoryError e){
    System.gc(); 
    //.. hedge recovery
}
Run Code Online (Sandbox Code Playgroud)

呼叫是System.gc()多余的吗?

是否已经保证 JVM(根据JVMS)在抛出之前运行了GC java.lang.OutOfMemoryError

Ste*_*ker 8

您永远不应该尝试通过运行System.gc()从OutOfMemoryError中恢复.无论是否严格保证,您都可以在JLS中找到.但这一直是一个糟糕的主意--JVM将尽最大努力满足你的内存分配需求.当它放弃并抛出一个OOM时,游戏就开始了.要么减少内存使用量,要么增加堆大小,然后再试一次.

为了更直接地回答你的问题,抓住一个OutOfMemoryError并不能意味着GC已运行.例如

try {
    throw new OutOfMemoryError();
} catch (OutOfMemoryError e) {
    ;
}
Run Code Online (Sandbox Code Playgroud)

可能不会调用GC.显然这是一个荒谬的例子.我最近看到的一个更现实的是OOME,原因是"无法分配新的本机线程".运行GC可能无法解决这种情况,因为JVM有剩余堆空间但系统不允许更多线程.


Art*_*tem 6

这里:

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

因此,GC无法释放更多内存抛出OutOfMemoryException .