1


return new JsonObject().put("name","xyz") 匿名对象是如何在堆中分配的,例如在返回语句的情况下使用:由于它们没有任何命名引用,垃圾收集器如何从内存中清除它们?我试图寻找答案,但找不到答案,所以在这里发布。

4

2 回答 2

2

如果一个实例在代码中不可用(可达),那么它就死了。当 gc 运行时,它会识别活动集,而不是死对象集。JVM 有自己的方法来跟踪活动对象。
收集器将跟踪活动集,标记所有活动对象。
然后收集器将根据类型将活动集移动到另一个内存区域(复制收集器)或遍历堆,在找到死对象时删除它们并可选地压缩堆。
在您的特定情况下,匿名对象没有特定引用的事实对 gc 并不重要,因为它有跟踪活动和死对象的方式。

于 2018-02-23T09:29:20.160 回答
1

这里有类似的问题;内部类对外部类有一个隐式引用,可能会泄漏内存和一个很好的描述http://viralpatel.net/blogs/inner-classes-in-java/

注意线;

内部类的对象具有对实例化它的外部类对象的隐式引用。

您可以在一个简单的测试中看到这一点;

    public class Frame1
    {
            public class JsonObject
            {
                    int field1 = 123;
                    int field2 = 456;

                    public JsonObject() { }
            }

            // code that callSomething()
            // ...

            private Object callSomething()
            {
                    return new JsonObject();
            }
    }

我在返回行上添加了一个断点,并允许代码走得足够远,因此创建了 JsonObject。然后在附加JVisualVM并查看我看到的堆上唯一的 JsonObject 实例之后;

在此处输入图像描述

有对外部Frame1类的引用

于 2018-02-23T00:41:29.717 回答