【问题标题】:new Thread() and Garbage Collectionnew Thread() 和垃圾回收
【发布时间】:2012-02-19 04:12:26
【问题描述】:

我有以下代码:

new Thread(new ThreadStart(delegate()
{
    while (true)
    {
        //something
    }
})).Start();

Thread 处于Running 状态时,垃圾收集器能否终结它?

【问题讨论】:

    标签: c# multithreading garbage-collection


    【解决方案1】:

    CLR 跟踪所有正在运行的线程。只要有对对象的引用,它们就不会被垃圾收集。由于 CLR 保留对所有正在运行的线程的引用,因此 GC 不会触及它们。

    【讨论】:

      【解决方案2】:

      没有;正在运行的线程算作根。不会收集正在运行的线程,也不会收集该线程的堆栈的活动部分引用的任何内容。

      【讨论】:

      • 正在运行的线程算作根?对对象的引用算作根的引用(在线程内).. ?
      • @Royi 根 - 基本上,堆栈本地人。请注意,arg0(又名 this)通常也会使目标实例保持活动状态
      • 那么说:GC 不允许收集正在运行的线程 是错误的吗?
      • @Royi 好吧,实际线程首先不是托管对象。 Thread 类型主要是一个帮助与 CLI 线程对话的实用程序,它有时是有时不是到 OS 线程的 1:1 映射(sql server 是“isnt”的一个例子)。
      • @Royi 这没有意义。这里唯一管理的是Thread,但那不是线程Thread 没有“里面”这样的东西。然而,thread 是一个根 - 并且不可收集。 Thread 是否可收集将是一个实现细节。
      【解决方案3】:

      线程不会被收集,因为每个运行、等待或挂起的线程本身都被 GC 用来决定什么是活动的(跟踪每个线程堆栈中的所有内容,跟踪所有这些对象引用的所有内容,然后所有引用的内容通过这些,等等,你已经确定了所有不能被垃圾收集的东西)。

      如果线程是后台线程,它可能会结束,因为当进程中的所有其他线程完成时,它将被主动关闭。否则,唯一会导致它死掉的是进程被主动退出、异常(包括ThreadAbortException)或者它本身脱离了while循环。

      有一个案例在某些方面具有可比性,这可能就是你所想的:

      var timer = new System.Threading.Timer(someCallback, null, new TimeSpan(0, 0, 5), new TimeSpan(0, 0, 5));
      int someResult = doingSomethingElse();
      doSomethingElseThatTakesLongerThan5Seconds();
      

      这是另一段代码,它导致另一个执行线程做某事。在这种情况下,计时器确实可以在运行之前、其中一次运行期间或构造函数返回后的几乎任何时间被垃圾收集。

      这里重要的是计时器没有单独的线程,并且线程甚至不“知道”计时器对象。由于对象的最后一次访问已经发生,因此它有资格被收集。这与正在运行(或等待等)的单个线程的问题不同。

      【讨论】:

        【解决方案4】:

        所有正在运行的计时器、线程、线程池和任务都被标记为 root。所以它们只会在它们完成(完成执行)时被垃圾回收,或者在应用程序关闭时被删除。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-11-13
          • 1970-01-01
          • 2011-08-01
          • 2015-12-27
          • 1970-01-01
          • 1970-01-01
          • 2011-12-21
          相关资源
          最近更新 更多