我已经通过了一些Java垃圾收集指南的在线阅读,但我还是有点不清楚,要问清楚,这样我就没有内存泄漏在我的代码。
难道Java的GC收集失去其参考对象,但它的变量仍然有借鉴意义?
所以我们可以说我有SomeObject:
public class SomeObject {
public ObjectVar var;
public SomeObject() {
var = new ObjectVar();
}
}
而我的代码:
SomeObject obj1 = new SomeObject();
SomeObject obj2 = new SomeObject();
obj2.var = obj1.var;
obj1 = null;
所以OBJ1的变种具有一定的参考,但OBJ1不再有任何引用。 因此,将在GC破坏OBJ1,但保持VAR活着吗? (我假设如此,只是想确认)。 谢谢!
这是发生什么事(见下面的评论)
// obj1 and obj1.var get created
SomeObject obj1 = new SomeObject();
// obj2 and obj2.var get created
SomeObject obj2 = new SomeObject();
// old obj2.var becomes eligible for GC
obj2.var = obj1.var;
// obj1 becomes eligible for GC
obj1 = null;
最终,两个对象仍然没有得到GCD - obj2
和前obj1.var
这是目前被引用为obj2.var
。
注:在特殊情况下ObjectVar
类是一个非静态内部类的SomeObject
,保持一个参考obj1.var
也将保持obj1
左右。 这是因为内部的SomeObject.ObjectVar
类有类型的隐藏变量SomeObject
,它引用了内部类的外部物体。
Yes of course.
Remember, what you store in the var
field is actually reference to the object, not the object itself. So when GC collects obj1
, the var
object is untouched (must not be touched), especially since it has a reference from obj2
, which is still alive and well..
是的 - 行为是你描述。 垃圾收集的一般规则是,当你无法通过任何硬引用到达他们的对象只有资格。 你能达到这样的任何对象将因此永远不会被垃圾收集(软/弱引用除外)。
简单地说,如果一个对象仍然是引用的路径到达,这是生存的保证集合。 如果没有这样的路径,该对象可以不再被访问,并可以安全地收集。
前两行后,内存看起来是这样的:
o1 --> SomeObj#1 --> ObjectVar#1
o2 --> SomeObj#2 --> ObjectVar#2
所有4个对象都可以达到,如果垃圾收集是在这个时候发生,没有人会被收集。
3号线后,它看起来像这样:
o1 --> SomeObj#1 --> ObjectVar#1
^
o2 --> SomeObj#2 ----- ObjectVar#2
现在,只有3个对象即可到达; 垃圾收集器可以移除ObjectVar#2。
4号线后,它看起来像这样:
o1 SomeObj#1 --> ObjectVar#1
^
o2 --> SomeObj#2 ----- ObjectVar#2
只有两个对象依旧可达; 垃圾收集器可以移除someObj中#1和ObjectVar#2,但必须保持someObj中#2和#ObjectVar 1。