在 .NET 中,线程在完成任务时会发生什么情况?我需要管理这个吗?

本文关键字:管理 什么情况 NET 线程 完成任务 | 更新日期: 2023-09-27 18:36:31

在完成 Console.WriteLine 后,我是否需要对此线程执行某些操作(挂起它或其他内容),或者垃圾回收会启动并删除此线程?

public void testThreading() {
    .. do some stuff
    var t = new Thread(() => { Console.WriteLine("hey!"); })
    t.Start();
}

在 .NET 中,线程在完成任务时会发生什么情况?我需要管理这个吗?

简短回答:

当线程完成其进程时,如果没有其他线程保存对它的引用,垃圾回收器将自动释放它。

长答案:

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

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

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

参考

垃圾回收的基础知识

从这里开始:-

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

受管线程不退出(及其线程堆栈的内存不释放),直到其 ThreadProc 返回或显式杀。因此,如果托管线程未正确终止,则内存分配给其线程堆栈将泄漏。

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