根源是什么?

垃圾回收的根源是什么?

我已经读过root的定义为“你编程可以访问的任何引用”,live的定义是正在使用的对象,它可以是局部变量,静态变量。

我有点混淆区分根和活物的区别。

什么是根路径? 根和活物体如何工作?

有人可以详细说明吗?


如果你将内存中的对象看作一棵树,那么“根”就是根节点 - 你的程序可以立即访问每个对象。

Person p = new Person();
p.car = new Car(RED);
p.car.engine = new Engine();
p.car.horn = new AnnoyingHorn();

有四个对象; 一个人,一辆红色的汽车,它的引擎和喇叭。 绘制参考图:

     Person [p]
        |
     Car (red)
   /           
Engine    AnnoyingHorn

而且你最终会在树的“根”处结束Person 。 它是活的,因为它被局部变量p引用,程序可能随时使用它来引用Person对象。 这也适用于其他对象,通过p.carp.car.engine等。

由于Person和所有其他递归连接的对象都是活的,如果GC收集它们,将会有麻烦。

但是,请考虑一段时间后是否会执行以下操作:

p.car = new Car(BLUE);

并重新绘制图表:

     Person [p]
        |
     Car (blue)       Car (red)
                    /           
                Engine    AnnoyingHorn

现在, Person可以通过p和蓝色车通过p.car ,但是再也无法再访问红色汽车或其部件 - 它们没有连接到活动根。 他们可以安全地收集。

所以它确实需要考虑每个起点(每个局部变量,全局变量,静态变量,其他线程和堆栈帧中的所有内容) - 每个根 - 并递归地跟随所有引用以构成所有“活动”对象的列表:正在使用且不适合删除的对象。 其他一切都是垃圾,等待收集。


GC(垃圾收集器)根目录是垃圾收集器特有的对象。 垃圾收集器收集那些不是GC根并且不能被来自GC根的引用访问的对象。

有几种GC根源。 一个对象可以属于多于一种的根。 根类型是:

  • 类 - 由系统类加载器加载的类。 这些类永远不能卸载。 他们可以通过静态字段来保存对象。 请注意,由自定义类加载器加载的类不是根,除非相应的java.lang.Class实例恰好是其他类型的根。
  • 线程 - 活线程
  • 堆栈本地 - Java方法的局部变量或参数
  • JNI Local - JNI方法的局部变量或参数
  • JNI Global - 全球JNI参考
  • 使用的监视器 - 用作同步监视器的对象
  • JVM保存 - JVM为实现其目的而从垃圾收集中保留的对象。 实际上,这些对象的列表取决于JVM的实现。 可能的已知情况是:系统类加载器,JVM知道的几个重要异常类,一些预分配的异常处理对象以及加载类时的自定义类加载器。 不幸的是,JVM绝对没有提供这些对象的额外细节。 因此,由分析人员决定某个“由JVM维护”属于哪种情况。
  • (记入YourKit网站)

    YourKit未提及的是,等待最终化的对象将作为根保留,直到GC运行finalize()方法。 这可能会导致暂时保留较大的图形,出乎意料。 一般的经验法则是不使用终结器(但这是一个不同的问题)。


    根或垃圾收集根是始终可达的对象。 如果一个对象总是可到达的,那么它不符合垃圾回收的条件; 因此根本没有资格收集。 它是确定堆中所有其他对象的可达性的初始对象集合。

    从垃圾收集根可访问的堆上的其他对象被视为活动对象,并且不适合收集; 无法访问的对象可以标记为回收。

    我比.Net平台更了解Java,所以我只会讲一个。 在Java平台上,GC根实际上是依赖于实现的。 然而,在大多数运行时中,GC根倾向于是堆栈上的操作数(因为它们当前由线程使用)和类(静态)成员的类。 可达性是从大多数JVM中的这些对象计算得出的。 在其他情况下,JNI调用使用的本地参数和操作数将被视为根集的一部分,并且还用于计算可达性。

    我希望这可以清除任何根源(集合)和什么是活的对象的疑惑。

    链接地址: http://www.djcxy.com/p/3349.html

    上一篇: What are the roots?

    下一篇: Easiest way to cause memory leak in Java?