|
|
1
9
不,只要一个线程被引用,它就被认为是活动的,任何正在运行的线程都被认为是被引用的(IIRC一个正在运行的线程将其堆栈注册为GC根,该堆栈将引用该线程)。 也就是说,我在看你的例子,我不明白你认为线程是从哪里产生的? |
|
|
2
5
不,为了GC的目的,运行线程的堆栈充当根。该堆栈将在线程运行时一直存在,因此线程本身不会在其运行时被收集。 |
|
|
3
3
你的问题有点难回答。就像Joel一样,据我所知,堆栈上没有引用计时器的内容,而计时器本身是唯一引用线程的内容。有鉴于此,可以预期将收集Thinker实例。 我对此很好奇,需要一个更具体的解释来解释可能发生的事情,所以我仔细研究了一下反射器。事实证明,System.Timers.Timer最终创建了一个System.Threading.Timer,它在内部创建了一个内部类TimerBase的实例。TimerBase派生自CriticalFinalizerObject,这是一种系统类型,可确保在实现类完全完成并被GC丢弃之前,约束执行区域(CER)中的所有代码都将执行。TimerBase也可以IDisposable,其dispose方法循环并旋转,直到释放锁。在这一点上,我开始运行外部代码,所以我不确定锁是如何初始化或释放的。 但是,基于TimerBase类的编写方式、它从CriticalFinalizerObject派生的事实以及它的dispose Spin等待锁释放的事实,我认为可以肯定地说,在代码执行完毕之前,没有被任何对象引用的线程将不会被终结。这就是说…重要的是要注意,它很可能会被GC处理…很可能不止一次,因为终结可以大大延长对终结对象的收集过程。对于那些关键的FinalizerObject,如果存在CER确保将完全执行的活动执行代码,则终结过程可能需要更长的时间。 这可能意味着,如果你的思考者需要一段时间来执行,你就会遇到完全相反的问题。这些对象不会过早地被收集,它们将进入一个漫长的定稿阶段,它们引用的任何东西最终都会在gen2中结束,并在GC最终能够完全收集它们之前存在相当长的一段时间。 |
|
|
4
2
如果我读对了(我可能离这里很远),它可以被收集,因为它是 目前正在做任何事情。 如果start方法中有局部变量,并且该方法仍然处于活动状态,那么这些变量仍然在堆栈上的“作用域”中,并为线程提供根。但是您使用的唯一变量是您的私有计时器,因为它是以线程本身为根的,并且线程在堆栈上没有任何内容,所以没有任何东西可以让它保持活动状态。 |
|
|
5
0
我同意也不同意,如果对thread对象的引用丢失,线程将被终止并被垃圾回收。在您的情况下,可能不是这样,因为它不是直接使用线程,而是使用计时器。但是,如果您在线程中调用了一个方法,并且该方法结束时线程引用丢失,那么它将被GC收集 |