微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java是否递归执行GC?

如何解决Java是否递归执行GC?

| 可能这是一个愚蠢的问题。 将对象标记垃圾回收时,java是否还会将包含的对象标记垃圾回收? 我的意思是,
class ContainerClass {
    ContainedClass obj1,obj2;  
    //Constructor
    ContainerClass() {
    obj1 = new ContainedClass ();
    obj2 = new ContainedClass ();
    }
  // main
    public static void main( String args[]) {
        ContainerClass  c = new ContainerClass();
        c = null ; // c is mared for GC. The question is c.obj1 and c.obj2 is also marked?
    }   
}
    

解决方法

        是的,如果只有ѭ1对象具有对它们的引用,那么
ContainedClass
对象将在
ContainerClass
对象本身变为合格的同时变为有资格进行垃圾回收。 请注意,这些对象的实际集合可以独立发生。     ,        您的问题在某些方面是从头到尾的。对象没有标记为要收集,而是标记为要保留。 垃圾收集器会根据找到的引用,从活动堆栈帧和所有静态变量等开始标记仍在使用的对象。垃圾收集器找到的每个对象都被标记为正在使用,不会被收集。 因此,不会将子对象标记为要收集,而只是将它们标记为不保留,因为它们的父对象也没有。 (对于“标记并清除垃圾收集器”确实是这样,这是大多数JVM的默认设置。其他垃圾收集器的行为可能有所不同。)     ,        如果没有活动线程直接或间接保存对该对象的引用,则该对象已准备好进行垃圾回收。所以是的,所包含的对象也准备好进行垃圾回收。     ,        对于您的特殊示例:是的,所包含的对象将被标记为gc,但不会,因为容器已收集。标记它们是因为在容器消失之后,没有其他对象持有对“ 2”实例的引用。 因此,总的来说,它不是递归的。如果可以收集每个实例,则将分别进行测试。所包含的实例不是容器类的一部分,它们过着自己的生活。容器只包含某种指针。     ,           Java是否递归执行GC? 不能。体面的垃圾收集器不会使用简单的递归进行标记。如果是这样,则标记较长的链表将需要标记算法使用非常深的堆栈对其进行标记。那将是一个重大问题。 GC实现者可以使用多种策略来避免过度递归: 您实际上并没有使用递归。您使用标记栈和迭代算法...这样可以节省空间。 遍历深层列表时,可以使用技巧来最小化堆栈深度。例如这是“ 5”字段。 Knuth和Boehm-Demers-Weiser具有处理溢出标记堆栈的方法,这些方法包括溢出标记堆栈,然后拾起碎片。 Deutsch-Schorr-Waite算法使用指针反转,因此完全没有标记栈。 等等。 如果您想了解更多详细信息,请参阅Richard Jones和Rafael Lins于1996年编写的“垃圾收集:自动动态内存管理算法”。(有一本新的GC书籍叫做“垃圾收集手册:自动的艺术” “内存管理”将由Richard Jones,Antony Hosking和Eliot Moss于今年晚些时候推出!) (不建议使用:GC不会将对象标记为垃圾回收。它会将其标记为非垃圾...,并丢弃未标记的对象。)     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。