2011-03-31 160 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頭文件。