java - 为什么此代码不能确保已完成完整的垃圾回收?

标签 java memory-management garbage-collection

previous answer中上forcing garbage collection , @shamsjslibs 中提出此方法:

/**
 * 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 to System.gc() are processed. If processing of calls to System.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/

相关文章:

C++自动内存: When is it deallocated?

iOS 上的 JavaScriptCore : VM Garbage Collector not automatically emtpying

android - admob 内存使用率高

java - 工厂模式和策略模式有什么区别?

java - 有没有办法将由 int 元素组成的直角三角形存储在二维数组中?

java - 从将为参数类型调用的 Java 类获取构造函数,不需要精确的参数和参数类型匹配

lua - 如何让Lua垃圾收集器更频繁地运行?

java - 忽略 token 正则表达式中的字符串

c++ - 具有显式大小的可用内存

c - 虚拟内存系统、页表和TLB