对象引用,线程和垃圾收集

时间:2016-06-15 06:48:56

标签: java multithreading garbage-collection

我了解垃圾收集器的一件事就是它拾取没有引用的对象。 让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();
 }

但是线程没有引用它,就像你知道我可以通过对象引用来创建线程但是我可能不想这样做。

  • 让线程执行一个漫长的运行任务,垃圾收集器将如何对此作出反应?
  • 从GC的角度来看,new MyClass();声明会发生什么......

3 个答案:

答案 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保留对所有正在运行的线程的引用,因此如果线程正在运行,它将不会被垃圾回收。此外,如果您的对象被正在运行的线程引用,则不会进行垃圾回收。