2013-09-30 29 views
2

我們對在特定計算機上遭受OutOfMemoryExceptions的NUnit測試進行了測試。運行測試時特定計算機上的OutOfMemoryException

調查後,似乎它不是一個內存問題,但處理問題(我們分配太多的位圖對象,而不是釋放它們)。

問題是,它在特定機器上完美運行,而在另一臺機器上出現此錯誤時失敗。

  1. 未按機在Hyper-V虛擬機使用的Windows7 64位(6 GB RAM)
  2. 工作機是一個物理機的Windows XP(2 GB RAM)

我知道,最好的解決辦法將清理處理任何Bitmap對象的代碼,但我有興趣知道爲什麼這兩臺機器在執行相同代碼時行爲不同?

+1

那麼,.NET框架可能是相同的,但底層操作系統不是。像位圖這樣的資源仍然由操作系統來處理。 Windows 7處理資源的方式與Windows XP不同,因此在不同版本的Windows上獲得不同的結果並不奇怪。 – helb

+0

在Windows拒絕發佈之前可以泄漏的句柄數量是可配置的。也許其中一臺機器配置不同。 –

+0

謝謝@eric。你知道這可以從哪裏控制嗎? –

回答

1

閱讀: http://blogs.technet.com/b/markrussinovich/archive/2010/02/24/3315174.aspx

你會發現各種版本的Windows之間的區別表相對於GDI堆。簡答:XP = 3Mb限制,Win7R2x64 = 20Mb限制。可用內存無關緊要,這些都是硬性限制。

+0

這不符合事實,在XP上它不會崩潰,並在Win7上它確實:( –

+1

可能發誓你的條件是他們現在的方式相反 – jlew

1

這種情況不太可能發生,Windows允許在泄漏10,000個句柄之前,它會讓程序表現出錯誤,並拒絕讓您分配更多內容。那時你已經爲位圖中的像素數據消耗了大量的虛擬內存空間。存儲在非託管內存中,垃圾收集器不知道它。除非調用Dispose()或垃圾收集器通過運行終結器來處理它,否則不會釋放VM空間。

GC通常不會完成工作,Bitmap類是一個非常小的對象,不足以觸發GC本身。你將不得不分配大約60,000個觸發GC。你永遠不會到達那裏,你將首先用完VM空間,除非位圖非常小,接下來處理。調用Dispose()是可選的,但由於終結器無法及時完成任務,停止對位圖進行選擇。

在這個內存中RAM的數量沒有任何作用,一個.NET程序總是轟炸它,無法在虛擬機地址空間找到足夠大以適應所需大小的洞。還有一個位圖問題,他們往往需要大的漏洞。它只需要一個DLL被加載到一個尷尬的基地址,將一個不錯的大洞切成兩個。否則,一個容易解決的問題,只需將程序的目標平臺設置爲AnyCPU即可。測試程序有一個配置值。適用於Win7機器。但是,當然,這不是跳過Dispose()調用的有效理由。

相關問題