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
后,没有使用列表
对象,因此从技术上讲,它在调用之后是不“需要”的,因此(这是我不确定保证的地方)对于垃圾收集本身可能是可省略的?或者调用框架的存在是否要求所有局部变量在所有条件下都是强根?即使是准时制?