Java垃圾收集器会回收包含对其他对象的引用的非引用对象吗? [英] Will Java garbage collector reclaim non-referenced object which contains reference to other objects

查看:89
本文介绍了Java垃圾收集器会回收包含对其他对象的引用的非引用对象吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题出现在我学习 LinkedList 数据结构时。假设每个链接(或节点)由包含两个字段的对象表示, data & next 指向下一个链接。如果我想删除特定节点,显然我会更新前一个链接的下一个字段。但是,我应该将已删除链接的 next 字段设置为null,以确保垃圾收集器将回收它?

如果我的描述不清楚,我会尝试概括(或简化)我的问题。假设一个 a 类的对象 a ,它有一个引用同一个类的另一个对象 a2 的字段。如果没有对象 a1 的引用,它是否有资格使用垃圾收集器?或者我们必须明确地将 a1 中的参考字段设置为 null ? (不关心对象 a2 ,除了 a1 中的引用字段外,还有其他引用)。

解决方案

垃圾收集器理想地收集程序流无法访问的所有对象。即使此对象具有对JVM中所有内容的引用。

如果所有正在运行的程序线程都不包含任何直接引用间接引用间接引用
直接引用如下所示:

  void main(String ... args){ 
Object a = new Object(); //< - 从这里程序的主线程
//引用了对象`a`
...
}

间接引用如下所示:

  void main(String。 .. args){
List b = new ArrayList();
b.add(new Object()); //< - 在这里你不能通过键入`a`
//来访问对象,如前例所示,但是你可以通过`b.get(0);`
//该对象可以间接访问 - >它是可达的。
}

它也可以正确处理大岛对象的情况,其他,但是没有一个可以从程序流程中获得。

  MyClass a = new MyClass(); 
MyClass b = new MyClass();
a.field = b;
b.field = a;
//此时a和b是可到达的,因此它们不能被收集
b = null;
//此时b的对象可通过`a.field`间接到达
//所以a和b都不能被收集
a = null;
//此时你既不能达到也不能得到b
//所以a和b可以被垃圾收集,
//尽管a被b所引用,反之亦然

UPD:添加了示例,更改了一些单词以使答案更清晰。

This question arises when I am learning the LinkedList data structure. Assume every Link (or Node) is represented by an object which contains two fields, data & next points to the next link. If I want to delete a specific node, clearly I will update the previous Link's next field. But should I set deleted link's next field to null, so as to make sure it will be reclaimed by the garbage collector ?

If my description is not clear, I try to generalize (or simplify) my question. Suppose an object a1 of class A which has a field, which references another object a2 of the same class. If there is no reference to object a1, will it be eligible for garbage collector ? Or we must explicitly set reference field in a1 to be null ? (don't care about object a2, there are other references to it besides the reference field in a1).

解决方案

Garbage collector ideally collect all objects, which are not reachable by program flow. Even if this object has references to everything in JVM.
Object becomes unreachable if all running threads of program don't contain any direct or indirect references to it.
Direct reference looks like this:

void main(String... args){
  Object a = new Object(); // <- from here main thread of program 
                           //    has reference to object `a`
  ...
}

Indirect reference looks like this:

void main(String... args){
   List b = new ArrayList();
   b.add(new Object()); // <- here you can't access object by typing `a`
   // as in previous example, but you can get access with `b.get(0);`
   // so that object can be accessed indirectly -> it is reachable.
}

It also handles properly cases of big isles of objects, which have references to each other, but none of which is reachable from program flow anymore.

MyClass a = new MyClass();
MyClass b = new MyClass();
a.field = b;
b.field = a;
// at this point a and b are reachable so they cannot be collected
b = null;
// at this point b's object is reachable indirectly through `a.field`
// so neither a nor b can be collected
a = null;
// at this point you cannot reach neither a nor b
// so a and b can be garbage collected, 
// despite the fact that a is referenced by b and vice versa

UPD: added examples, changed some words to make answer clearer.

这篇关于Java垃圾收集器会回收包含对其他对象的引用的非引用对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆