Java “之后对象是否有资格进行垃圾收集”;obj=null";?

Java “之后对象是否有资格进行垃圾收集”;obj=null";?,java,garbage-collection,Java,Garbage Collection,我知道System.gc()不一定会导致gc,但理论上,在下面的代码中,对象obj是否符合垃圾收集的条件 public class Demo { public static void main(String[] args) throws Exception { SomeClass obj = new SomeClass(); ArrayList list = new ArrayList(); list.add(obj);

我知道
System.gc()
不一定会导致gc,但理论上,在下面的代码中,对象
obj
是否符合垃圾收集的条件

public class Demo {

    public static void main(String[] args) throws Exception {
        SomeClass obj = new SomeClass();
        ArrayList list = new ArrayList();
        list.add(obj);
        obj = null;
        System.gc();
    }

}

class SomeClass {
    protected void finalize() {
        System.out.println("Called");
    }
}

同意,只要它在列表中,它就不会被垃圾收集。

在调用
System.gc()
时,您创建的
SomeClass
实例不符合垃圾收集的条件,因为它仍然被
list
对象引用,即它仍然可以访问

但是,只要此方法返回
list
就超出范围,因此
obj
将有资格进行垃圾收集(与
list
一样)


仅仅将reference
obj
设置为null本身并不能使引用的对象符合垃圾收集的条件。只有在可见对象图中没有对对象的引用时,对象才符合条件。

没有,因为该对象实际上存在于列表中。

作为Java程序员,您不能在Java中强制垃圾收集;只有当JVM认为它需要基于Java堆大小的垃圾收集时,才会触发它

当Java程序启动时,Java虚拟机从操作系统获取一些内存。Java虚拟机或JVM使用此内存满足其所有需要,其中一部分内存称为Java堆内存

Java中的堆通常位于地址空间的底部并向上移动。每当我们使用new操作符或通过任何其他方式创建对象时,对象从堆中分配内存,当对象死亡或垃圾回收时,内存返回到Java中的堆空间

编辑:

对象obj是否有资格进行垃圾收集

public class Demo {

    public static void main(String[] args) throws Exception {
        SomeClass obj = new SomeClass();
        ArrayList list = new ArrayList();
        list.add(obj);
        obj = null;
        System.gc();
    }

}

class SomeClass {
    protected void finalize() {
        System.out.println("Called");
    }
}
否,因为对象仍在ArrayList中

对象obj是否有资格进行垃圾收集

public class Demo {

    public static void main(String[] args) throws Exception {
        SomeClass obj = new SomeClass();
        ArrayList list = new ArrayList();
        list.add(obj);
        obj = null;
        System.gc();
    }

}

class SomeClass {
    protected void finalize() {
        System.out.println("Called");
    }
}
只有那些连一个引用都没有的对象才被垃圾收集。(循环连接除外)

在代码中,有两个引用指向
newsomeclass()

  • obj
  • 列表的第0个索引
  • 您将obj=null放入
    obj
    ,即它不再指向该对象。但是,列表中仍然存在另一个可用于访问该对象的引用


    因此,只有当
    main
    返回时,对象才有资格使用GC。i、 e.即使调用了
    finalize
    方法,也看不到该方法的输出。(不确定JVM是否仍然调用它)

    也不能保证
    finalize
    将被调用not Qualified,因为您的obj引用为null,但在仍然可以访问的现有列表中。虽然答案是“否”(假设变量始终是强根),但这是一个有趣的问题。在.NET/C#中,SomeClass对象可能会被垃圾收集,因为[稍后]不会使用
    list
    。这是一个实际的.NET问题,在长时间运行的方法中存在计时器回调。问题是:在Java中,可见堆栈上的每个变量是否总是保证为强根?问题是该对象是否符合垃圾收集的条件。是的,他符合条件。他还指出,他知道这不会强制进行垃圾收集。您还没有回答以下问题:“对象
    obj
    是否有资格进行垃圾收集?”当您将obj设置为null时,它在列表中是否也会变为null?列表只是指向obj之前所在的位置。否。Java使用引用,而不是指针。将项目添加到列表时,它会获取引用的副本并存储该副本。更改原始引用不会更改复制的引用,因此仍然可以访问
    SomeClass
    实例。同意,在上述情况下不会对其进行垃圾收集。答案是否。请尽快阅读“Head First Core Java”。哪里可以保证
    list
    是强根?(我确信它在某些规范中:-)调用
    System.gc
    后,没有使用
    列表
    对象,因此从技术上讲,它在调用之后是不“需要”的,因此(这是我不确定保证的地方)对于垃圾收集本身可能是可省略的?或者调用框架的存在是否要求所有局部变量在所有条件下都是强根?即使是准时制?