2011-01-13 54 views
2

我正在開發一個64位.Net Windows服務應用程序,它基本上會加載一堆用於處理的數據。在執行數據量測試時,我們能夠壓倒進程,並拋出OutOfMemoryException異常(當失敗時,我沒有關於進程的任何性能統計信息)。我很難相信進程請求一大塊內存自從它在64位機器上運行以來,已經超過了該進程允許的地址空間。我知道這個過程在一臺機器上運行,這臺機器的物理內存使用率一直在80%-90%左右。我的問題是:如果計算機的可用物理內存嚴重不足,CLR是否會拋出OutOfMemoryException,即使該進程不會超過其允許的虛擬內存量?虛擬和物理內存/ OutOfMemoryException

感謝您的幫助!

+0

它仍然限於分頁文件的最大大小。在達到可尋址內存限制之前,您會達到這個目標。 – 2011-01-13 17:20:25

回答

4

在64位環境中仍存在一些可達到的限制。請查看this page瞭解一些最常見的問題。簡而言之,是的,如果你的程序將大量的128GB數據加載到虛擬內存中,你仍然可能會耗盡內存。如果您沒有設置IMAGE_FILE_LARGE_ADDRESS_AWARE環境變量,那麼您仍可能受限於每個進程限制2GB的限制。

+0

+1。很好的答案,很好的聯繫。 – David 2011-01-13 16:01:27

1

有什麼可以從理論上解決。

你有什麼樣的物理知識,你是否超過了開始使用swap的速度,而swap通常僅限於某些選定磁盤分區的大小。

作爲一個經驗法則,一個物理內存的倍數往往會有少量(如一個或兩個)爲交換。

所以是的,這很可能是你沒有可用的,而不是尋址內存。

4

另一種可能性是程序試圖分配一個大於2GB的內存塊,這是一個.NET限制。添加的東西集合時就會發生這種情況(最常見的是DictionaryHashSet,也List或自動增加任何其他集合。)

DictionaryHashSet做到這一點的時候,如果你試圖把超過約收集4700萬件物品。雖然該集合可以容納大約89.5百萬個,但是增加集合的算法通過加倍來實現。如果您從一個空的Dictionary開始並開始添加項目,該收藏會翻倍,直到達到約4700萬。然後它再次嘗試翻倍並投擲OutOfMemoryException

避免異常的方法是預先分配集合,使其容量足夠大,以容納您期望放入其中的許多項目。

+0

預先分配集合,使其容量足夠大,以容納您期望放入其中的許多項目。你能告訴我如何在HashSet的情況下做到這一點,即預分配?我可以在列表中做到這一點,但是對於HashSet呢? – 2011-12-27 06:54:48