2011-03-31 158 views
13

什么是C#.NET 2.0中线程允许的最大堆栈大小?此外,该值是否取决于CLR的版本和/或底层操作系统的位数(32或64)? 我已经看过以下资源msdn1msdn2最大线程堆栈大小.NET?

public Thread( ThreadStart start, int maxStackSize )

我可以看到的唯一信息是默认大小为1兆字节和在上面的方法中,如果maxStackSize是“0”的默认最大堆将使用头文件中为可执行文件指定的大小,那么我们可以将头中的值改为最大值的最大值是多少?也建议这样做?谢谢。

+0

[推动Windows的限制:进程和线程](http://blogs.technet.com/b/markrussinovich/archive/2009/07/08/3261309.aspx)可能很有趣。但它并不直接回答这个问题。 – 2011-03-31 23:27:45

+0

确实很有意思。感谢分享。 – Oved 2011-04-01 00:08:39

回答

4

我不知道的最大的是什么,但MSDN对你说话是否应该做不做:使用此构造函数重载

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

我从来没有在C#中发生StackOverflow,这不是由于无限递归造成的。如果确实存在递归达到这种深度的情况,我会考虑用迭代替换它。

+0

谢谢克里斯。我有一个后台线程,对一组文件进行长时间操作,并且因'内存不足以继续执行程序'错误而失败。通过更改maxStackSize值,此问题一度得到解决。现在对于不同的文件集,它会失败并出现相同的错误,我试图将值设置为最大可能值并查看结果。此外,只是对最大值感到好奇,因为我无法找到它。 – Oved 2011-04-01 00:24:09

24

为了记录,这适合雷蒙德陈的“如果你需要知道,你做错了什么”类别。

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

分配超过默认值是非常不必要的。你可能会考虑这样做,当你有一个沉重的递归方法吹堆栈。不要,修正这个算法,或者当这个工作变得越来越大时,你会把它吹掉。

.NET允许您选择的最小堆栈是250 KB。如果你传递一个更小的值,它会默默地将它四舍五入。必要的,因为抖动和垃圾收集器都需要堆栈空间来完成他们的工作。再次,这样做应该是不必要的。如果你考虑这么做是因为你有很多线程并且使用它们的堆栈消耗了所有的虚拟内存,那么你有太多的线程。 StackOverflowException是您可以获得的最差的运行时异常之一。程序死亡是直接的和不可接受的。

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