在previous answer中上forcing garbage collection , @shams从 jslibs 中提出此方法:
/**
* This method guarantees that garbage collection is done unlike <code>{@link System#gc()}</code>
*/
public static void gc() {
Object obj = new Object();
WeakReference ref = new WeakReference<Object>(obj);
obj = null;
while (ref.get() != null) {
System.gc();
}
}
但是在 a comment , @MarkoTopolnik不同意此方法保证垃圾收集完成这一事实。
我不明白为什么检查弱引用对象是否已被垃圾化不是一个证明?
最佳答案
The java
command manual entry提供确凿的证据,证明 System.gc()
不保证会导致垃圾回收。在“高级垃圾收集选项”部分中,描述了此选项:
-XX:+DisableExplicitGC
Enables the option that disables processing of calls to
System.gc()
. This option is disabled by default, meaning that calls toSystem.gc()
are processed. If processing of calls toSystem.gc()
is disabled, the JVM still performs GC when necessary.
当 System.gc()
的 javadoc 谈到“尽力而为”时,这可能意味着“根本不努力”。
你说:
I don't understand why checking if a weak referenced object have been garbaged is not a proof ?
你的“证明”是基于一个谬论,最好的说明是:
<小时/>Today I painted my letterbox and my kitten died.
Can I logically conclude that every time I paint my letterbox, a kitten will die?
Does it also apply if someone else paints a letterbox? Or if I paint my front gate?
还有另一个原因导致您的示例在不同 JVM 上的行为可能有所不同。
当您将 null
分配给 obj
时,该方法作用域的其余部分中不会读取该变量。因此,编译器可以优化分配。如JLS 17.4说:
"The memory model describes possible behaviors of a program. An implementation is free to produce any code it likes, as long as all resulting executions of a program produce a result that can be predicted by the memory model."
"This provides a great deal of freedom for the implementor to perform a myriad of code transformations, including the reordering of actions and removal of unnecessary synchronization."
如果分配被优化掉,那么 GC 可以看到变量中先前的非空值,认为对象仍然可达,并且不会破坏 WeakReference
。
我无法告诉您是否存在具有类似行为的 Java 实现,但我认为 1) JLS 允许这样做,2) 这是 JIT 编译器执行的合理优化。
关于java - 为什么此代码不能确保已完成完整的垃圾回收?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28475391/