9

在它完成 Console.WriteLine(暂停它或其他什么)之后,我是否需要对这个线程做一些事情,或者垃圾收集会启动并删除这个线程?

public void testThreading() {

    .. do some stuff

    var t = new Thread(() => { Console.WriteLine("hey!"); })
    t.Start();

}
4

3 回答 3

11

简短的回答:

当一个线程完成它的进程时,如果没有其他东西持有对它的引用,垃圾收集器将自动处理它。

长答案:

垃圾收集器被 CLR 初始化后,它会分配一段内存来存储和管理对象。此内存称为托管堆,而不是操作系统中的本机堆。每个托管进程都有一个托管堆。

进程中的所有线程都为同一堆上的对象分配内存。为了保留内存,垃圾收集器调用 Win32 VirtualAlloc 函数,并一次为托管应用程序保留一段内存。垃圾收集器还根据需要保留段,并通过调用 Win32 VirtualFree 函数将段释放回操作系统(在清除它们的任何对象之后)。在堆上分配的对象越少,垃圾收集器要做的工作就越少。分配对象时,不要使用超出需要的四舍五入值,例如只需要 15 个字节时分配 32 个字节的数组。当触发垃圾回收时,垃圾回收器会回收被死对象占用的内存。

回收过程压缩活动对象,使它们一起移动,并删除死空间,从而使堆更小。这确保了一起分配的对象一起留在托管堆上,以保持它们的位置。垃圾回收的侵入性(频率和持续时间)是分配量和托管堆上幸存内存量的结果。堆可以认为是两个堆的堆积:大对象堆和小对象堆。大对象堆包含 85,000 字节或更大的非常大的对象。大对象堆上的对象通常是数组。实例对象非常大是很少见的。

参考

垃圾收集的基础知识

于 2013-10-22T21:40:48.830 回答
4

这里:-

托管线程的生命周期独立于创建它的 Thread 对象,这是一件非常好的事情,因为您不希望 GC 仅仅因为丢失对关联 Thread 对象的所有引用而终止仍在工作的线程。所以 GC 正在收集 Thread 对象,而不是实际的托管线程。 .....................

托管线程在其 ThreadProc 返回或被显式终止之前不会退出(并且不会释放其线程堆栈的内存)。因此,如果托管线程未正确终止,分配给其线程堆栈的内存将泄漏。

于 2013-10-22T21:42:08.850 回答
2

根据这个答案,“线程的代码执行完毕后,线程将被停止并回收其资源。”

于 2013-10-22T21:41:07.940 回答