【问题标题】:What prevents a Thread in C# from being Collected?是什么阻止了 C# 中的线程被收集?
【发布时间】:2015-12-02 18:35:30
【问题描述】:

在 .NET 中,在这段代码之后,什么机制可以阻止 Thread 对象被垃圾回收?

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

是的,假设 something 引用了该线程是安全的,我只是在徘徊到底是什么。由于某种原因,Reflector 没有显示System.Threading,所以我自己无法挖掘它(我知道 MS 发布了 .NET 框架的源代码,我只是手边没有它)。

【问题讨论】:

    标签: .net multithreading garbage-collection


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      这取决于线程是否正在运行。如果你刚刚创建了 Thread 对象并没有启动它,它是一个普通的托管对象,即符合 GC 条件。一旦你启动线程,或者当你为已经运行的线程(GetCurrentThread)获取线程对象时,它就有点不同了。 “公开对象”,托管线程,现在在 CLR 中保持强引用,因此您始终获得相同的实例。当线程终止时,这个强引用被释放,并且一旦你没有任何其他对(现在已经死的)线程的引用,托管对象就会被收集。

      【讨论】:

        【解决方案3】:

        这是垃圾收集器的硬连线功能。不收集正在运行的线程。

        【讨论】:

          【解决方案4】:

          好吧,可以安全地假设,如果某个线程正在某个地方运行,那么某些东西对它有引用,那么这不足以停止垃圾收集吗?

          【讨论】:

            【解决方案5】:

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

            【讨论】:

              【解决方案6】:

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

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

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

              【讨论】:

              • 不,不会。运行时保留一个引用。否则,如果您丢失引用,将收集正在运行的线程。
              猜你喜欢
              • 1970-01-01
              • 2011-05-08
              • 2015-04-22
              • 1970-01-01
              • 2017-03-13
              • 2020-11-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多