2017-03-02 23 views
2

我有一個本機C++應用程序,我正在調用.net dll(外部函數),我發現當我打電話給託管時,它分配完整的堆棧分配對於使用/ stack連接器選項指定的線程,但是如果我只進行本機函數調用,它會分配計算所需的堆棧。混合模式下的內存使用過多C++/CLR應用程序

下面是我的觀察

設置爲80MB /堆棧選項,並通過調用外部管理功能。 enter image description here

將/ stack選項設置爲1MB,並調用託管的外部函數。 enter image description here

將/ stack選項設置爲80MB,並調用本地內部函數。 enter image description here

當我們調用.Net外部函數時,還有一些額外的線程與GC有關。與我們不調用.Net外部函數的情況相比,我們的應用程序中的線程也使用了更多的堆棧空間。我不確定託管堆棧是否位於本地堆棧之上。有人可以幫助我理解爲什麼當我們調用.Net外部函數以及混合模式應用程序中的內存管理時,爲線程分配了全部堆棧。

回答

2

好的,我終於找到答案。

一旦創建託管線程,CLR就會始終爲託管線程提交整個堆棧內存,或者在本地線程變爲託管線程時,CLR始終提交。這是爲了確保堆棧溢出可以由執行引擎預測處理。

在託管代碼中,System.Threading.Thread類的構造函數提供了兩個接受maxStackSize參數的重載。由於完整堆棧在創建時爲所有託管線程提交,因此maxStackSize參數同時表示備用和提交大小:它們實際上是相同的。

只是爲了澄清,有三個步驟,使用堆棧內存:

儲備堆棧的過程中 提交頁面 使用

在正常的默認行爲頁面的虛擬地址空間當一個線程啓動時,Win32程序只做1個。問題在於動態堆棧增長在高負載下可能會失敗 - 您可能會發現當您想添加堆棧幀時,系統沒有任何可用的空閒虛擬內存。

通過執行步驟2,CLR確保內存將保留在備用狀態,以便第3步永遠不會失敗。

有關此任何有用的信息仍然讚賞。 謝謝。

相關問題