2015-11-15 31 views
3

我正在使用.NET中的struct類型的大型array,這比爲堆棧(每個線程)分配的標準1MB大得多。我只關心現在的主線。我是否需要在.NET中顯式調整堆棧大小?

  1. 我已閱讀,提到明確調整您的堆舊文章(可能是過時的):http://content.atalasoft.com/h/i/58213648-increasing-the-size-of-your-stack-net-memory-management-part-3

  2. 我注意到,我的節目經常與stackoverflow exceptions崩潰時,在32位模式下而不是在64位模式(我的主要興趣模式)。

暫定假設

  1. 你需要明確增加堆棧的大小,當你在32位模式下。

  2. .NET框架以64位模式隱式調整堆棧大小(即使此行爲與64位模式不一致)。

+2

在.NET中,數組是引用類型,它們位於堆上。堆棧溢出錯誤是由於你的代碼,所以你應該發佈一些。 –

+0

檢查此[回覆](http://stackoverflow.com/a/20744680/1849444),希望這可以幫助 –

回答

4

C#和VB.NET編譯器沒有辦法指定主線程的初始堆棧大小。 C++/CLI編譯器可以。在post-build event中使用Editbin.exe是一種簡單的解決方法。

此選項未公開,因爲默認堆棧大小爲非常適合託管代碼。與像C和C++這樣的非託管語言不同,沒有簡單的方法來使用聲明來消費大量的堆棧。數組和字符串是引用類型,因此分配在GC堆上,而不是堆棧上。

打擊堆棧的唯一體面的方式是使用不安全的stackalloc關鍵字,一個你從不偶然使用的關鍵字。或者通過遞歸,無論是偶然的(迄今爲止最常見的情況)還是使用比O(logN)更差的遞歸算法。這些問題嚴重傾向於錯誤,Editbin.exe僅僅是一種創可貼,因爲當數據集足夠大時,您仍會吹動堆疊。

只有其他值得注意的細節是,如果您的具體爲目標x64,則初始堆棧大小將爲4MB,而不是1MB。通常也是一個錯誤,你總是喜歡AnyCPU。


因此,否則盲目的建議是開始尋找遞歸代碼。它不應該與生成SOE的語句相距太遠,至少在堆棧跟蹤中可見。注意O(N)尾部草書,你不能指望它得到優化,絕對不是32位代碼。考慮替換它或對其進行分區或添加一個檢查到數據集大小並預先拋出異常。

+0

我認爲值得詳細說明尾調用優化,這是x86和x64 JIT行爲之間的顯着差異,其中拋出StackOverflowException的傾向比線程堆棧大小更大的影響。 –

相關問題