我了解垃圾收集器的一件事就是它拾取没有引用的对象。
让MyClass
成为一个类,我通过
MyClass object = new MyClass();
即使我的代码执行
,我也可以使它符合垃圾收集的条件object = null;
但是没有对象引用的对象发生了什么,比如下面的语句。
new MyClass();
我对线程非常关注,我可以通过代码来创建和执行线程。
public static void main(String args[])
{
new Thread() {
public void run() {
try {
System.out.println("Does it work?");
Thread.sleep(1000);
System.out.println("Nope, it doesnt...again.");
} catch(InterruptedException v) {
System.out.println(v);
}
}
}.start();
}
但是线程没有引用它,就像你知道我可以通过对象引用来创建线程但是我可能不想这样做。
new MyClass();
声明会发生什么...... 答案 0 :(得分:3)
GC会查看堆栈跟踪的所有活动线程,因此Thread
没有来自main
线程的引用,但它来自当前正在执行的线程(新创建的线程)
GC从所谓的GC根查找可到达的对象,其中一个根是所有线程。
答案 1 :(得分:2)
...没有参考的对象......
让我们清楚一下这意味着什么。有关GC的讨论通常会将可跟踪的对象与 GC根中的对象区分为无法跟踪的对象。
“Traceable”表示您从gc根开始跟随一系列对象引用,并最终到达相关对象。 gc根基本上是程序中的所有static
变量,并且每个活动方法的所有参数和所有局部变量都在每个线程中调用。
“活动方法调用”表示已发生相应return
尚未发生的调用。
因此,如果某个线程中的某些活动方法具有对Foo
实例的引用,并且Foo
实例具有对Bar
实例的引用,并且{{1} instance有一个Bar
实例的引用;然后Baz
实例是“可追踪的”,并且不会被收集。
在每个线程中,在线程堆栈上的Baz
调用之下都有方法激活,并且这些方法激活中的至少一个具有对管理线程的run()
实例的引用。因此,Thread
对象永远不会是GCd,而它管理的线程仍在运行。
此外,在JVM黑暗的某个地方,有一个所有Thread
实例的静态列表,因此它们都不会是GCd。
答案 2 :(得分:1)
JVM保留对所有正在运行的线程的引用,因此如果线程正在运行,它将不会被垃圾回收。此外,如果您的对象被正在运行的线程引用,则不会进行垃圾回收。