WeakReferenced 对象在调用 System.gc() 后不会被垃圾回收

1 java garbage-collection reference 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!");
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Mic*_*ael 6

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

文档

调用 gc 方法表明Java 虚拟机花费精力来回收未使用的对象,以使它们当前占用的内存可用于快速重用。当控制从方法调用返回时,Java 虚拟机已尽最大努力从所有丢弃的对象中回收空间。

(强调我的)

将来,您可以使用 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
Run Code Online (Sandbox Code Playgroud)

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

如果您删除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!");
    }
}
Run Code Online (Sandbox Code Playgroud)