当前位置: 首页 > 面试题库 >

调用System.gc()后,不会对WeakReferenced对象进行垃圾回收。

端木兴国
2023-03-14
问题内容

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

所以我做了这个小测试:

import java.lang.ref.WeakReference;

html" target="_blank">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()只是运行垃圾收集器的 提示 。它经常被忽略。

从文档中:

调用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

除非在这两个指令之间进行垃圾收集,否则将不会对对象进行垃圾收集。

如果删除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!");
    }
}


 类似资料:
  • 问题内容: 我要求显式垃圾回收器调用。但是窗口并没有从屏幕上消失,为什么垃圾回收器不回收JFrame的对象? 问题答案: 当被创建时,它注册本身在一些内部摇摆的数据结构,其允许它接收到类似的鼠标点击的事件。这意味着在您告诉Swing使用摆脱窗口之前,存在对潜伏在某处的对象的引用。

  • 问题内容: 我有一个Java应用程序正在泄漏内存。我知道在垃圾回收期间哪些对象没有被释放,但是我无法确定引用它们的对象。 JVM内部保存的对象图是否具有某种可见性? 否则就有可能找出哪些对象引用了另一个对象? 问题答案: 在真正的基础上,您可以使用命令jhat和jmap从正在运行的Java进程中读取堆文件,然后对其进行处理- 它在本地端口上启动小型Web服务器。它并不是很容易阅读,但是您不必购买分

  • 在下面的代码中,假设调用了。最初引用的对象在哪一点/哪一行符合垃圾收集的条件? 如果或有一个公共、受保护、默认或静态的访问修饰符,它会影响对象在什么点上有资格进行垃圾收集吗?如果是,它会受到什么影响? 我的第一个想法是,当测试对象有资格进行垃圾收集时,该对象有资格进行垃圾收集

  • 有人能给我解释一下原因吗?

  • 问题内容: 我很好奇嵌套函数的node.js模式如何与v8的垃圾收集器一起工作。这是一个简单的例子 如果restofprogram是长时间运行的,那是否不意味着str将永远不会被垃圾回收?我的理解是,使用结点,您最终会获得很多嵌套函数。如果在外部声明了restofprogram,是否会收集垃圾,因此str不能在范围内?这是推荐做法吗? 编辑 我不想使问题复杂化。那只是粗心,所以我修改了它。 问题答

  • 根据这个问题的答案,在第11行没有符合GC条件的对象;但是根据我的说法,至少有一个对象t2,它在第6行被设置为指向null,应该有资格进行垃圾回收。