C#.NET 2.0中线程允许的最大堆栈大小是多少?此外,此值是否取决于CLR的版本和/或底层操作系统的位数(32或64)? 我查看了以下资源msdn1和msdn2
public Thread(
ThreadStart start,
int maxStackSize
)
我能看到的唯一信息是默认大小为1兆字节,在上面的方法中,如果maxStackSize为'0',将使用可执行文件头中指定的默认最大堆栈大小,最大值是多少我们可以更改标题中的值吗?这样做也是可取的吗?感谢。
答案 0 :(得分:25)
为了记录,这符合Raymond Chen的类别“如果你需要知道你做错了什么”。
运行64位代码的线程的默认堆栈大小为4兆字节,32位代码为1兆字节。虽然Thread构造函数允许您将整数值传递给int.MaxValue,但您永远不会在32位机器上获得该值。堆栈必须适合虚拟内存地址空间中的可用空洞,通常在进程生命周期的早期大约为600 MB。在分配内存和分割地址空间时,它会迅速变小。
分配超过默认值是非常不必要的。当你有一个强大的递归方法来吹掉堆栈时,你可能会想到这样做。不要,修复算法,否则当工作变大时你就会把它吹掉。
.NET允许您选择的最小堆栈为250 KB。如果你传递一个更小的值,它会默默地将它向上舍入。必要的是因为抖动和垃圾收集器都需要堆栈空间才能完成工作。同样,这样做应该是非常不必要的。如果您考虑这样做是因为您有很多线程并且使用堆栈消耗所有虚拟内存,那么您有太多线程。 StackOverflowException是您可以获得的最糟糕的运行时异常之一。过程死亡是即时的,无法解决的。
主线程的堆栈大小由EXE头中的选项确定。编译器没有更改它的选项,您必须使用editbin.exe / stack来修补.exe标头。
答案 1 :(得分:3)
我不知道最大值是多少,但MSDN会说明你是否应该这样做:
避免使用此构造函数重载。 Thread(ThreadStart)构造函数重载使用的默认堆栈大小是线程的建议堆栈大小。如果线程有内存问题,最可能的原因是编程错误,例如无限递归。
我从来没有在C#中出现StackOverflow,这不是由于无限递归造成的。如果确实存在递归到达该深度的情况,我会考虑用迭代替换它。