新的Thread()和垃圾收集

时间:2012-01-25 23:13:43

标签: c# multithreading garbage-collection

我有以下代码:

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

垃圾收集器可以在Thread状态下完成此Running实例吗?

4 个答案:

答案 0 :(得分:21)

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

答案 1 :(得分:13)

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

答案 2 :(得分:2)

不会收集线程,因为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();

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

这里重要的是没有用于计时器的单独线程,并且线程甚至不“知道”关于计时器对象。自从上次访问该对象以来,它有资格进行收集。这与正在运行(或等待等)的单个线程的问题不同。

答案 3 :(得分:0)

所有正在运行的计时器,线程,线程池和任务都标记为root。因此,只有在完成(完成执行)后才会对它们进行垃圾收集,或者在应用程序关闭时将其删除。