【问题标题】:Object References,Threads and Garbage collection对象引用、线程和垃圾收集
【发布时间】:2016-06-15 06:48:56
【问题描述】:

我对垃圾收集器的了解很少,其中之一是它会拾取没有引用的对象。 让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();
 }

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

  • 让线程在做一个长时间运行的Task,垃圾收集器会如何反应?
  • 从 GC 的角度来看,new MyClass(); 语句会发生什么...

【问题讨论】:

    标签: java multithreading garbage-collection


    【解决方案1】:

    GC 查看所有活动线程的堆栈跟踪,因此您的Thread 没有来自main 线程的引用,但它来自当前正在执行的线程(新创建的线程)。

    GC 从所谓的 GC 根中寻找可达对象,根之一是所有线程。

    【讨论】:

      【解决方案2】:

      ...没有引用的对象...

      让我们弄清楚这意味着什么。关于 GC 的讨论经常将 可追踪GC 根 的对象与不可追踪 的对象区分开来。

      “可追踪”意味着,您从 gc 根开始遵循一系列对象引用,并最终到达有问题的对象。 gc根基本上就是程序中所有的static变量,以及每个线程中每个活动方法调用的所有参数和所有局部变量。

      “活动方法调用”表示已发生调用,但尚未发生对应的return

      所以,如果某个线程中的某个活动方法引用了Foo 实例,而Foo 实例引用了Bar 实例,而Bar 实例引用了@ 987654327@实例;那么Baz 实例是“可追踪的”,不会被收集。

      在每个线程中,在线程堆栈上的run() 调用下方都有方法激活,并且这些方法激活中至少有一个引用了管理线程的Thread 实例。因此,Thread 对象在其管理的线程仍在运行时永远不会被 GCd。

      此外,在 JVM 的某个阴暗处,有一个包含所有 Class 实例的静态列表,因此它们都不会被 GCd。

      【讨论】:

        【解决方案3】:

        JVM 保留对所有正在运行的线程的引用,因此如果一个线程正在运行,它将不会被垃圾收集。此外,如果您的对象被正在运行的线程引用,则不会被垃圾回收。

        【讨论】:

          猜你喜欢
          • 2011-01-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-11
          • 1970-01-01
          • 2012-07-09
          相关资源
          最近更新 更多