对象内对象的内存分配

时间:2015-07-24 15:58:45

标签: java performance object memory-management garbage-collection

据我所知,如果对象A引用了对象B作为其实例变量,则引用存储在堆上为对象A分配的空间中。但是对象B本身存储在堆上的其他位置,在为对象A分配的空间之外。

这种理解准确吗?以这种方式进行内存分配有什么好处(而不是在堆上的对象A中有对象B)?

这(正面或负面)对Java垃圾收集机制的性能有何影响(即如果对象A被破坏)?

3 个答案:

答案 0 :(得分:2)

其中一个主要好处是对象的独立性 - 如果B在A中分配,B只能在收集A时收集。

作为堆上的单独对象,B现在可以在其他地方传递和引用,与A无关,而B将具有自己的生命周期。

垃圾收集器将知道何时没有对任何一个对象的进一步根引用 - 例如即使收集了A,也可能还有其他对B的引用会延长其使用寿命。

答案 1 :(得分:0)

B个实例也可以独立创建,也可以用作其他对象的实例字段,例如:对象C。如果您在BA内有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,BC s是独立节点(顶点)并且它们引用图中的连接箭头(边缘),这大大简化了。

答案 2 :(得分:0)

您建议的内容("对象"在其父对象的内存中烘焙)将由http://openjdk.java.net/jeps/169覆盖。另请参阅histogram