最大线程堆栈大小.NET?

Posted

技术标签:

【中文标题】最大线程堆栈大小.NET?【英文标题】:Maximum Thread Stack Size .NET? 【发布时间】:2011-07-27 07:50:35 【问题描述】:

C#.NET 2.0 中线程允许的最大堆栈大小是多少?此外,此值是否取决于 CLR 的版本和/或底层操作系统的位数(32 或 64)? 我查看了以下资源 msdn1 和 msdn2

public Thread(
    ThreadStart start,
    int maxStackSize
)

我能看到的唯一信息是默认大小为 1 兆字节,在上述方法中,如果 maxStackSize 为 '0',则将使用在头文件中为可执行文件指定的默认最大堆栈大小,最大值是多少我们可以将标题中的值更改为?也建议这样做吗?谢谢。

【问题讨论】:

Pushing the Limits of Windows: Processes and Threads 可能很有趣。但它并没有直接回答这个问题。 确实,很有趣。感谢分享。 【参考方案1】:

为了记录,这符合 Raymond Chen 的“如果你需要知道,那么你做错了什么”的类别。

运行 64 位代码的线程的默认堆栈大小为 4 兆字节,32 位代码为 1 兆字节。虽然 Thread 构造函数允许您将整数值传递给 int.MaxValue,但在 32 位机器上您永远无法得到它。堆栈必须适合虚拟内存地址空间中的可用孔,通常在进程生命周期的早期达到约 600 MB。随着您分配内存和分割地址空间,它会迅速变小。

分配超过默认值是完全没有必要的。当你有一个大量递归的方法会破坏堆栈时,你可能会考虑这样做。不要,修复算法,否则当工作变得更大时,无论如何你都会搞砸它。

.NET 允许您选择的最小堆栈为 250 KB。如果您传递一个较小的值,它会默默地四舍五入。这是必要的,因为抖动和垃圾收集器都需要堆栈空间来完成它们的工作。同样,这样做应该是完全没有必要的。如果您考虑这样做是因为您有很多线程并使用它们的堆栈消耗所有虚拟内存,那么您有太多线程。 ***Exception 是您可以获得的最糟糕的运行时异常之一。进程死亡是立即的且无法捕获的。

主线程的堆栈大小由 EXE 标头中的选项确定。编译器没有选项可以改变它,你必须使用 editbin.exe /stack 来修补 .exe 头。

【讨论】:

【参考方案2】:

我不知道最大值是多少,但 MSDN 说明了您是否应该这样做:

避免使用此构造函数重载。 Thread(ThreadStart) 构造函数重载使用的默认堆栈大小是线程的推荐堆栈大小。如果线程出现内存问题,最可能的原因是编程错误,例如无限递归。

我从来没有在 C# 中发生过 ***,这不是由于无限递归。如果真的有递归到那个深度的情况,我会考虑用迭代代替它。

【讨论】:

谢谢克里斯。我有一个后台线程,它对一组文件执行长时间操作,并因“内存不足,无法继续执行程序”错误而失败。此问题曾经通过更改 maxStackSize 值得到修复。现在对于不同的文件集,它失败并出现相同的错误,我试图将值设置为可能的最大值并查看结果..也只是对最大值感到好奇,因为我找不到它。

以上是关于最大线程堆栈大小.NET?的主要内容,如果未能解决你的问题,请参考以下文章

单声道下的堆栈大小

.net 中线程的 RAM 和 CPU 限制

我是不是需要在 .NET 中显式确定堆栈的大小?

一个进程最多包含多少个线程

实时监控 Java 中的总线程堆栈大小

线程的堆栈