如果堆已满,JVM 会抛出一个
OutOfMemoryError
. 但是,是否保证在抛出此类异常之前总是进行(完整)垃圾收集?
这意味着当抛出异常时,只有强引用对象(或 GC Roots 可访问)内存已满。
编辑:假设 Sun JVM - HotSpot 正在讨论中。
如果堆已满,JVM 会抛出一个
OutOfMemoryError
. 但是,是否保证在抛出此类异常之前总是进行(完整)垃圾收集?
这意味着当抛出异常时,只有强引用对象(或 GC Roots 可访问)内存已满。
编辑:假设 Sun JVM - HotSpot 正在讨论中。
Java 机器规范在第 6.3 节(强调我的)中指出:
OutOfMemoryError
:Java 虚拟机实现已用完虚拟内存或物理内存,并且自动存储管理器无法回收足够的内存来满足对象创建请求。
因此,JVM 确实保证它会在抛出 OOME 之前尝试通过垃圾收集来释放内存。
垃圾收集器通常会在抛出 OutOfMemoryError 之前运行。但是,如果您没有 GC,您可能会获得 OOME
You are not guaranteed that a full garbage collection has been performed, but that the VM has tried to make enough memory available through garbage collection. You could have found that in the API documentation for the OutOfMemoryError class:
Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.
Note that there are cases where the garbage collector can decide that enough memory is not available without actually trying to discard unreferenced object instances. The most obvious example is if you try to allocate more memory in one go (e.g. a large byte array) than the max heap size. In this case, an OutOfMemoryError may be thrown without the garbage collector being run at all.
除了人们已经回答的问题之外,还有其他额外的因素需要考虑,例如您正在使用的垃圾收集策略。考虑吞吐量垃圾收集,如果花费太多时间收集并且没有释放足够的内存(尽管最近的更改可能已经改变了一些事情),这将引发内存不足异常。说了这么多,我不会假设在我正在编写的应用程序的执行过程中的任何时候都会发生垃圾收集......
不能保证前面的最后一个操作OutOfMemoryError
是垃圾收集。很可能不会,因为垃圾收集会减少使用的内存量而不是增加它。