java - WeakReferenced 对象在调用 System.gc() 后未被垃圾回收

标签 java reference garbage-collection weak-references

我是 Java 的新手。我现在正在学习 WeakReference 的概念。我遇到了一个可能看起来很愚蠢的问题,但我只想找出原因。问题是:根据 Java 文档,“弱引用对象,不会阻止其引用对象成为可终结的、最终确定的,然后被回收。”

所以我做了这个小测试:

import java.lang.ref.WeakReference; 

public class A {
    public static void main(String[] args) {
        A a = new A();
        WeakReference<A> wr = new WeakReference<>(a);
        a = null;

        A a1 = wr.get();

        System.out.println(a);
        System.out.println(a1);

        try {
            System.gc();

            Thread.sleep(10000);

        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println(a1);
    }

    @Override
    protected void finalize( ) {
        System.out.println(Thread.currentThread().getName() + ": See ya, nerds!");
    }
}

但是,我注意到在GC运行之后,wr.get()仍然可以返回我期望的null对象,并且finalize()方法没有被调用。那么出了什么问题呢?提前感谢您的帮助! :)

最佳答案

您的测试前提存在缺陷。 System.gc() 只是运行垃圾收集器的提示。它经常被忽略。

来自 the documentation :

Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

(强调我的)

将来,您可以使用 VM 选项 -verbose:gc-XX:+PrintGCDetails 来查看垃圾收集器正在做什么。


更重要的是,您还非常快从弱引用中取出引用并将其放回强引用中:

A a = new A();
WeakReference<A> wr = new WeakReference<>(a);
a = null; // no strong references remain
A a1 = wr.get(); // the instance now has a strong reference again

除非在这两条指令之间发生垃圾回收,否则对象不会被垃圾回收。

如果您删除 a1,您的代码将按照我运行时的预期运行(尽管,由于我回答的第一部分,您的里程可能会有所不同):

class A
{
    public static void main(String[] args)
    {
        A a = new A();
        WeakReference<A> wr = new WeakReference<>(a);
        a = null;

        System.out.println(a);

        try {
            System.gc(); // instance of A is garbage collected
            Thread.sleep(10000);

        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println(wr.get());
    }

    @Override
    protected void finalize( )
    {
        System.out.println(Thread.currentThread().getName() + ": See ya, nerds!");
    }
}

关于java - WeakReferenced 对象在调用 System.gc() 后未被垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50718490/

相关文章:

java - 如何在 ListView 中选定的列表项上设置自定义默认铃声?

ANT - 检索当前任务名称

java - 错误对话框未被销毁

java - 多线程垃圾回收

java - 试图理解 java 中的垃圾收集

java - Android Studio 中的多个 onClick 事件

java - Fragment 内的 DialogFragment 内的 RecyclerView

java - 使用 AlphanumComparator

c# - 使用什么序列化程序(到 xml)进行循环引用和自定义字段?

java - 为什么在将对象类型更改为泛型后,我仍然能够将任何对象添加到具有原始类型引用类型的列表中?