调用System.gc()后,不会对WeakReferenced对象进行垃圾回收. [英] WeakReferenced object is not garbage collected after calling System.gc()

查看:243
本文介绍了调用System.gc()后,不会对WeakReferenced对象进行垃圾回收.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java的新手.我现在正在学习WeakReference的概念.我遇到了一个看起来可能很愚蠢的问题,但我只是想找出原因.问题是:根据Java文档,弱引用对象,它们不会阻止对其引用进行最终化,最终确定和回收".

I am a fresh new learner of Java. I'm now learning the concept of WeakReference. I came across a problem which probably looks stupid but I just wanna figure out the reason. The problem is: according to Java doc, "Weak reference objects, which do not prevent their referents from being made finalizable, finalized, and then reclaimed."

所以我做了这个小测试:

So I did this small test:

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().那么出了什么问题呢?感谢您的提前帮助! :)

However, I noticed that after GC running, wr.get() could still return object which I expected null, and the method finalize() was not invoked. So what went wrong? Thanks for your kind help in advance! :)

推荐答案

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

The premise of your test is flawed. System.gc() is only a hint to run the garbage collector. It is frequently ignored.

来自文档:

调用gc方法建议,即Java虚拟机 致力于回收未使用的物品,以使 它们当前占用的内存可用于快速重用.何时控制 从方法调用返回的结果,Java虚拟机取得了最佳效果 努力从所有丢弃的对象中回收空间.

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来查看垃圾收集器在做什么.

In future, you may use the VM options -verbose:gc and -XX:+PrintGCDetails to see what the garbage collector is doing.

更重要的是,您也非常快将参考从弱参考中剔除,然后重新放入强参考中:

More importantly, you are also very quickly taking the reference out of the weak reference and putting it back into a strong reference:

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

除非这两个指令之间发生垃圾回收,否则将不会对该对象进行垃圾回收.

Unless garbage collection occurs between these exact two instructions, the object will not be garbage collected.

如果删除了a1,则您的代码会像我运行它时所期望的那样运行(尽管由于回答的第一部分,您的工作量可能会有所不同):

If you remove a1, your code behaved as you would expect when I ran it (though, because of the first part of my answer, your mileage may vary):

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!");
    }
}

这篇关于调用System.gc()后,不会对WeakReferenced对象进行垃圾回收.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆