【问题标题】:Anonymous object Creation and GC匿名对象创建和GC
【发布时间】:2018-02-22 20:31:02
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 你可能会指出这个问题的矛盾之处:如果有一个对对象的命名引用,它就没有资格进行垃圾回收。换句话说,由于对象总是在没有没有引用时被收集,所以在对象的过去是否有命名引用并不重要。
    • @Holger 是的,我本来可以的,但似乎有一些我不想添加的想法。
    【解决方案2】:

    这里有类似的问题; 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 实例之后;

    有对外部Frame1类的引用

    【讨论】:

      猜你喜欢
      • 2011-09-17
      • 2019-09-15
      • 1970-01-01
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多