java垃圾回收根对象_java中的垃圾收集器 – 将对象设置为null

Java中的垃圾收集是基于“可达性”执行的. JLS将术语定义如下:

“A reachable object is any object that can be accessed in any potential continuing computation from any live thread.”

只要对象可以访问*,就不符合垃圾回收的条件.

JLS将其留给Java实现来确定如何确定对象是否可访问.如果实现不能确定,可以将理论上无法访问的对象视为可达…而不是收集它. (事实上??,JLS允许实现不会收集任何东西!尽管如此,没有合理的实现会这样做.)

在实践中,(保守的)可达性通过追踪来计算;通过以下从类(静态)变量开始的引用和线程堆栈上的局部变量来查看可以达到的内容.

以下是这对您的问题意味着什么:

If i call: myTree = null; what really happens with the related TreeNode objects inside the tree? Will be garbage collected as well, or i have to set null all the related objects inside the tree object??

假设myTree包含对树根的最后剩余可到达引用.

>没有立即发生.

>如果以前只能通过根节点访问内部节点,则它们现在无法访问,并且有资格进行垃圾回收. (在这种情况下,为内部节点的引用分配null是不必要的.)

>但是,如果内部节点可通过其他路径到达,则可能仍然可以访问它们,因此不符合垃圾回收的条件. (在这种情况下,为内部节点的引用分配null是一个错误.您正在拆除其他人可能稍后尝试使用的数据结构.)

如果myTree不包含对树根的最后剩余可到达引用,则归零内部引用是错误的,原因与上面的3.相同.

那么什么时候应该为了垃圾收集器而无效?

您需要担心的情??况是,您可以确定某个单元格(本地,实例或类变量或数组元素)中的引用不会再次使用,但编译器和运行时不能!案件大致分为三类:

>类变量中的对象引用……(根据定义)永远不会超出范围.

>仍在范围内的局部变量中的对象引用…但不会被使用.例如:

public List pigSquadron(boolean pigsMightFly) {

List airbornePigs = new ArrayList();

while (...) {

Pig piggy = new Pig();

...

if (pigsMightFly) {

airbornePigs.add(piggy);

}

...

}

return airbornePigs.size() > 0 ? airbornePigs : null;

}

在上面,我们知道如果pigsMightFly为false,则不会使用list对象.但是,预计没有主流的Java编译器可以解决这个问题.

>实例变量或数组单元格中的对象引用,其中数据结构不变量意味着它们不会被使用. @ edalorzo的堆栈示例就是一个例子.

应该注意的是,编译器/运行时有时会发现范围内的变量实际上已经死了.例如:

public void method(...) {

Object o = ...

Object p = ...

while (...) {

// Do things to 'o' and 'p'

}

// No further references to 'o'

// Do lots more things to 'p'

}

一些Java编译器/运行时可能能够检测到循环结束后不需要’o’,并将变量视为死.

*事实上,我们在这里谈论的是强大的可达性.当您考虑软,弱和幻像参考时,GC可达性模型会更复杂.但是,这些与OP的用例无关.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值