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

Java 为什么此代码不能确保已完成完整的垃圾回收?,java,memory-management,garbage-collection,Java,Memory Management,Garbage Collection,在on中,从以下方面提出此方法: 但是在中,我们不同意这样一个事实,即此方法保证垃圾收集完成 我不明白为什么检查弱引用对象是否已被丢弃不是证据?作为开发人员,您不能强制垃圾收集器运行,您所能做的就是请求它。JVM将决定它是否运行 对此您无能为力。作为一名开发人员,您不能强制垃圾收集器运行,您所能做的就是请求它。JVM将决定它是否运行 您对此无能为力。如上所述,java垃圾收集无法强制执行。。。但这是可以帮助的。 因此,好的java代码在完成变量时总是将其置零,因为置零变量的行为会引起垃圾收集器的

在on中,从以下方面提出此方法:

但是在中,我们不同意这样一个事实,即此方法保证垃圾收集完成


我不明白为什么检查弱引用对象是否已被丢弃不是证据?

作为开发人员,您不能强制垃圾收集器运行,您所能做的就是请求它。JVM将决定它是否运行


对此您无能为力。

作为一名开发人员,您不能强制垃圾收集器运行,您所能做的就是请求它。JVM将决定它是否运行


您对此无能为力。

如上所述,java垃圾收集无法强制执行。。。但这是可以帮助的。 因此,好的java代码在完成变量时总是将其置零,因为置零变量的行为会引起垃圾收集器的兴趣

类似地,垃圾收集器比其他引用更严格地维护弱引用,这本质上就是弱引用的目的。但是,您必须记住,如果只有定义类本身具有对弱引用的引用,那么弱引用将被收集。这意味着您不能使用弱引用代替普通引用


管理垃圾收集的艺术是一个很大的课题,它在Java实现之间有所不同。例如,Android java比Oracle java更积极地进行垃圾收集。

如上所述,java垃圾收集无法强制执行。。。但这是可以帮助的。 因此,好的java代码在完成变量时总是将其置零,因为置零变量的行为会引起垃圾收集器的兴趣

类似地,垃圾收集器比其他引用更严格地维护弱引用,这本质上就是弱引用的目的。但是,您必须记住,如果只有定义类本身具有对弱引用的引用,那么弱引用将被收集。这意味着您不能使用弱引用代替普通引用

管理垃圾收集的艺术是一个很大的课题,它在Java实现之间有所不同。例如,Android java比Oracle java更积极地进行垃圾收集。

提供了确凿的证据证明
System.gc()
不一定会导致垃圾收集。在“高级垃圾收集选项”部分,它描述了此选项:

-XX:+DisableExplicitGC

启用禁用对
System.gc()
调用处理的选项。默认情况下禁用此选项,这意味着将处理对
System.gc()
的调用。如果对
System.gc()
的调用的处理被禁用,JVM在必要时仍然执行gc

System.gc()
的javadoc谈到“尽最大努力”时,这可能意味着“根本不努力”


你说:

我不明白为什么检查一个弱引用对象是否被丢弃不是证据

你的“证明”是基于一个谬误,最好的例证是:

今天我画了我的信箱,我的小猫死了

我是否能从逻辑上得出这样的结论:每次我画信箱时,都会有一只小猫死去

如果其他人在信箱上涂色,它也适用吗?或者如果我粉刷前门


还有另一个原因可以解释为什么您的示例在不同的JVM上表现不同

当您将
null
赋值给
obj
时,该方法作用域的其余部分中没有任何内容读取该变量。因此,编译器可以优化分配。正如上面所说:

内存模型描述程序的可能行为。只要程序的所有结果执行产生内存模型可以预测的结果,实现就可以自由生成它喜欢的任何代码

“这为实现者提供了执行大量代码转换的极大自由,包括重新排序操作和删除不必要的同步。”

如果分配被优化掉,那么GC可以在变量中看到以前的非空值,处理仍然可以访问的对象,并且不破坏
WeakReference

我不能告诉您是否有这样的Java实现,但我认为1)JLS允许这样做,2)JIT编译器执行这样的优化是合理的。

提供了确凿的证据证明
System.gc()
不一定会导致垃圾收集。在“高级垃圾收集选项”部分,它描述了此选项:

-XX:+DisableExplicitGC

启用禁用对
System.gc()
调用处理的选项。默认情况下禁用此选项,这意味着将处理对
System.gc()
的调用。如果对
System.gc()
的调用的处理被禁用,JVM在必要时仍然执行gc

System.gc()
的javadoc谈到“尽最大努力”时,这可能意味着“根本不努力”


你说:

我不明白为什么检查一个弱引用对象是否被丢弃不是证据

你的“证明”是基于一个谬误,最好的例证是:

今天我画了我的信箱,我的小猫死了

我是否能从逻辑上得出这样的结论:每次我画信箱时,都会有一只小猫死去

如果其他人在信箱上涂色,它也适用吗?或者如果我粉刷前门


还有另一个原因可以解释为什么您的示例在不同的JVM上表现不同

当您将
null
赋值给
obj
时,该方法作用域的其余部分中没有任何内容读取该变量。因此,编译器可以优化分配。正如所说
/**
 * 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();
    }
}