据我所知,如果对象A引用了对象B作为其实例变量,则引用存储在堆上为对象A分配的空间中。但是对象B本身存储在堆上的其他位置,在为对象A分配的空间之外。
这种理解准确吗?以这种方式进行内存分配有什么好处(而不是在堆上的对象A中有对象B)?
这(正面或负面)对Java垃圾收集机制的性能有何影响(即如果对象A被破坏)?
答案 0 :(得分:2)
其中一个主要好处是对象的独立性 - 如果B在A中分配,B只能在收集A时收集。
作为堆上的单独对象,B现在可以在其他地方传递和引用,与A无关,而B将具有自己的生命周期。
垃圾收集器将知道何时没有对任何一个对象的进一步根引用 - 例如即使收集了A,也可能还有其他对B的引用会延长其使用寿命。
答案 1 :(得分:0)
B
个实例也可以独立创建,也可以用作其他对象的实例字段,例如:对象C
。如果您在B
或A
内有C
个实例,则需要"复制" B
周围,或C
引用A
获取B
(显然不是一个好主意)。
所以对象有自己的分配空间,当需要引用其他对象的特定实例时,它们只存储一个"指针"相反,他们的位置。
另外,按照您的示例,如果您有以下代码:
class A {
private B myB = new B();
public B getB() { return this.myB; }
}
和某些代码(例如来自对象C)调用B myB = myA.getB();
,然后您不希望将C
的实例绑定到A
。如果A
获得GC' d C
仍可保持其B
正常。这是因为B
未与A
或其他任何内容耦合(内存方式)。
最后,与最后一点相关,请记住GC基于对象图,并且只收集无法访问的节点。 A
s,B
和C
s是独立节点(顶点)并且它们引用图中的连接箭头(边缘),这大大简化了。
答案 2 :(得分:0)
您建议的内容("对象"在其父对象的内存中烘焙)将由http://openjdk.java.net/jeps/169覆盖。另请参阅