匿名对象创建和GC

时间:2018-02-22 20:31:03

标签: java garbage-collection heap-memory anonymous-objects

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

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

这里也有类似的问题; Inner Class has an implicit reference to the outer class and may can leak memory以及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实例;

enter image description here

有一个对外Frame1

的引用