其中是C#中分配的任务堆栈

本文关键字:任务 堆栈 分配 | 更新日期: 2023-09-27 18:00:16

我们都知道诸如Task之类的方法。运行并行。ForEach它们中的每一个都创建了任务,这些任务根据单独线程或线程池中的线程中的选项运行。但是,它们的堆栈在哪里?在某一代堆或有特殊的地方为他们?

例如,我可以创建1000个任务,它们的堆栈位于哪里?如果我打电话给GC,他们的物理地址会在某个时候移动吗。Collect()?

其中是C#中分配的任务堆栈

堆栈是一个纯非托管的实现细节。处理器需要一个堆栈来完成任何事情,没有它就无法有意义地执行任何代码。它与线程(普通CLR主机上的另一个纯非托管细节)强绑定。

它位于操作系统内核在创建线程时决定分配它的内存中,它是随机的。故意随机地给恶意软件带来困难,堆栈是将数据转化为恶意代码的一种有吸引力的方式。不仅位置是随机的,堆栈开始的堆栈段内的确切偏移也是随机的。

它在创建后永远不会移动,GC也不会对它进行修补。它确实需要了解它,对象根可以存储在堆栈上。因此,可靠的堆栈行走很难。NET要求,这也是CLR在程序因未处理的异常而终止时始终可以生成良好堆栈跟踪的基本原因。堆栈空间不足是一个严重的问题,处理器无法继续执行代码。严重到可以用这个问题命名程序员的网站:)

基于TaskScheduler执行的委托的任务在TaskScheduler使用的任何堆栈上运行。默认调度程序使用线程池线程。这些(大部分)是正常的。NET线程。

特别地,Task.Run创建这样一个基于调度器的默认任务。

基于TaskCompletionSource的任务不执行代码,也不需要堆栈。它们是根据一些外部条件完成的,例如IO完成或计时器计时。

NET没有内置的对基于堆的堆栈或"绿色线程"的支持。您通常不会在实际代码中找到这样的东西。