【发布时间】:2018-02-22 20:31:02
【问题描述】:
匿名对象是如何使用的,例如用于返回语句的情况:return new JsonObject().put("name","xyz")
在堆中分配?由于它们没有任何命名引用,垃圾收集器如何从内存中清除它们?我试图寻找答案,但找不到答案,所以在这里发布。
【问题讨论】:
标签: java garbage-collection heap-memory anonymous-objects
匿名对象是如何使用的,例如用于返回语句的情况:return new JsonObject().put("name","xyz")
在堆中分配?由于它们没有任何命名引用,垃圾收集器如何从内存中清除它们?我试图寻找答案,但找不到答案,所以在这里发布。
【问题讨论】:
标签: java garbage-collection heap-memory anonymous-objects
如果代码中的实例不可用(可访问),那么它就死了。当 gc 运行时,它会识别 活动集,而不是死对象集。 JVM 有自己的方法来跟踪活动对象。
收集器将跟踪活动集,标记所有活动对象。
然后收集器将根据类型将活动集移动到另一个内存区域(复制收集器)或遍历堆,在找到死对象时删除它们并可选地压缩堆。
在您的具体情况下,匿名对象没有特定引用这一事实对 gc 来说并不重要,因为它有自己的方式来跟踪活对象和死对象。
【讨论】:
这里有类似的问题; 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类的引用
【讨论】: