对象内对象的内存分配
Memory allocation for objects within objects
据我了解,如果对象 A 将对象 B 的引用作为其实例变量,则该引用将存储在堆上为对象 A 分配的 space 中。但是对象 B 本身存储在堆上的其他地方,在为对象 A 分配的 space 之外。
这个理解准确吗?以这种方式进行内存分配有什么好处(相对于在堆上的对象 A 中有对象 B)?
这对 Java 的垃圾收集机制(即如果对象 A 被销毁)的性能有什么影响(正面或负面)?
其中一个主要好处是对象的独立性——如果 B 在 A 中分配,则 B 只能在收集 A 时收集。
作为堆上的独立对象,B 现在可以在别处传递和引用,独立于 A,并且 B 将拥有自己的生命周期。
垃圾收集器将知道何时不再有对任一对象的根引用 - 例如即使收集了 A,也可能还有其他对 B 的引用,这将延长其生命周期。
B
s 实例也可以独立创建,或者它们可以用作其他对象的实例字段,例如对象 C
。如果在 A
或 C
中有 B
实例,则需要 "copy" B
左右,或者让 C
引用 A
得到 B
(显然不是一个好主意)。
所以对象有自己的分配 space,当它们需要引用其他对象的特定实例时,它们只是将 "pointer" 存储到它们的位置。
此外,按照您的示例,如果您有以下代码:
class A {
private B myB = new B();
public B getB() { return this.myB; }
}
和一些代码,比如来自对象 C,调用 B myB = myA.getB();
,那么您不想将 C
的实例绑定到 A
的实例。如果 A
得到 GC,C
仍然可以保持它的 B
就好了。这是因为 B
没有耦合(内存方面)到 A
或其他任何东西。
最后,与最后一点相关,请记住 GC 是基于对象图的,并且只收集无法到达的节点。 A
s、B
s 和 C
s 是独立的节点(顶点)并且它们引用图中的连接箭头(边),这大大简化了。
您提出的建议("Objects" 在其父对象的内存中烘焙)将被 value types. See also http://openjdk.java.net/jeps/169
涵盖
据我了解,如果对象 A 将对象 B 的引用作为其实例变量,则该引用将存储在堆上为对象 A 分配的 space 中。但是对象 B 本身存储在堆上的其他地方,在为对象 A 分配的 space 之外。
这个理解准确吗?以这种方式进行内存分配有什么好处(相对于在堆上的对象 A 中有对象 B)?
这对 Java 的垃圾收集机制(即如果对象 A 被销毁)的性能有什么影响(正面或负面)?
其中一个主要好处是对象的独立性——如果 B 在 A 中分配,则 B 只能在收集 A 时收集。
作为堆上的独立对象,B 现在可以在别处传递和引用,独立于 A,并且 B 将拥有自己的生命周期。
垃圾收集器将知道何时不再有对任一对象的根引用 - 例如即使收集了 A,也可能还有其他对 B 的引用,这将延长其生命周期。
B
s 实例也可以独立创建,或者它们可以用作其他对象的实例字段,例如对象 C
。如果在 A
或 C
中有 B
实例,则需要 "copy" B
左右,或者让 C
引用 A
得到 B
(显然不是一个好主意)。
所以对象有自己的分配 space,当它们需要引用其他对象的特定实例时,它们只是将 "pointer" 存储到它们的位置。
此外,按照您的示例,如果您有以下代码:
class A {
private B myB = new B();
public B getB() { return this.myB; }
}
和一些代码,比如来自对象 C,调用 B myB = myA.getB();
,那么您不想将 C
的实例绑定到 A
的实例。如果 A
得到 GC,C
仍然可以保持它的 B
就好了。这是因为 B
没有耦合(内存方面)到 A
或其他任何东西。
最后,与最后一点相关,请记住 GC 是基于对象图的,并且只收集无法到达的节点。 A
s、B
s 和 C
s 是独立的节点(顶点)并且它们引用图中的连接箭头(边),这大大简化了。
您提出的建议("Objects" 在其父对象的内存中烘焙)将被 value types. See also http://openjdk.java.net/jeps/169
涵盖