垃圾收集和后台线程如何在.NET中交互?

时间:2010-01-14 18:56:40

标签: .net multithreading garbage-collection

假设我创建了一个对象,该对象启动一个线程,并将其私有实例方法之一提供给ThreadStart。之后,对该对象的所有引用都消失了。怎么了?该对象是否永远不会被垃圾收集,因为该线程通过this指针保存对它的引用?另一方面,如果我使用静态方法,线程如何检测其对象是否被垃圾收集并结束?

我知道我通常不应该让线程的生命周期依赖于垃圾收集。我不希望我的物体在没有正确放置时泄漏。

2 个答案:

答案 0 :(得分:4)

除了通过委托间接持有的任何引用之外,创建线程不会直接引用该对象。该线程使用ThreadStart开始运行,但它不包含正在运行的委托之外的引用。

如果方法是实例方法,则在线程方法完成之前,不会对对象进行垃圾回收。委托需要对对象实例的引用,并使其保持root。当线程委托完成时,有问题的对象变为无根,并且可以用于垃圾收集。

如果是静态方法,这不是问题。没有对实例的引用 - 仅对类型有引用。启动线程的实例将不会被新创建的线程引用 - 因此它将一直运行直到完成它的方法,然后关闭。实例的垃圾收集处理方式与线程不存在时相同(即:当其他引用消失时,该对象将可用于GC)。

答案 1 :(得分:0)

如果将委托存储到某个实例方法(例如通过将其提供给线程),则委托将包含对该对象的引用,该对象将存储在TreadObject中的某个位置,因此该对象不会被垃圾回收直到线程结束。

如果给ThreadStart一个静态方法,委托将不包含对实例的任何引用,因此垃圾收集器不会受到线程存在的阻碍(至少涉及到有问题的对象)