C#中有什么阻止线程被回收的因素?

17

在.NET中,完成以下代码后,什么机制防止 Thread 对象被垃圾收集?

new Thread(Foo).Start();
GC.Collect();

是的,可以安全地假设某个东西与线程有关,我只是想知道具体是什么。由于某种原因,Reflector不显示System.Threading,因此我无法自行查找(我知道MS发布了.NET框架的源代码,只是我手头没有它)。

6个回答

16

只要线程在运行,运行时会持有对该线程的引用。只要有任何人仍然保留对该引用的引用,GC就不会收集该线程。


9

这取决于线程是否正在运行。如果你只是创建了Thread对象但没有启动它,那么它就是一个普通的托管对象,即可被垃圾回收。一旦你启动线程,或者当你获取已经运行线程的Thread对象(GetCurrentThread)时,情况会有所不同。"暴露的对象",即托管的Thread,在CLR中被强引用持有,因此你总是得到相同的实例。当线程终止时,这个强引用将被释放,而托管对象将在你没有任何其他对(现在死亡的)Thread的引用时被收集。


2

这是垃圾回收器的固有特性。正在运行的线程不会被回收。


0

嗯,可以安全地假设如果某个线程正在运行,那么肯定有某个引用指向它,这不就足以阻止垃圾回收了吗?


0
需要注意的重要一点是 - 如果您的线程标记为IsBackground=True,它将不会阻止整个进程退出。

-3

将新线程分配给本地字段?

class YourClass
{
  Thread thread;

  void Start()
  {
    thread = new Thread(Foo);
    thread.Start();
    GC.Collect();
  }
}

垃圾回收会收集所有未被引用的内容,因此在您的代码中没有字段/变量引用线程,因此它将被回收。


2
不会的。运行时保留引用。否则,如果您失去引用,正在运行的线程将被回收。 - EricSchaefer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接