簡體   English   中英

System.OutOfMemoryException因為大字典

[英]System.OutOfMemoryException because of Large Dictionary

我在字典中保留了一個大緩存,其值為IEnumerable<KeyValuePair<DateTime, Double>> 我會定期從字典中刪除項目,並定期將項目添加到字典中。 我一次又一次得到一個System.OutOfMemoryException。 我想知道垃圾收集器為什么不來救我?

請記住,正如@Gabe所提到的那樣,堆可能會碎片化。 即使你可能有空閑內存,它也可能沒有足夠大的塊來分配字典,當它執行它時調整大小。

也許您可以使用模式和實踐庫MSDN Library Link中的緩存塊來幫助您實現良好的緩存。 也許你可以選擇一個不動態分配內存的算法,具有固定數量的條目?

另請注意,如果沒有可以使用的內存,那么緩存大小就會出現問題,而不是垃圾收集器。

這很可能是GC 來拯救你了很多的時間,但是,你只是超越其能力的時候。

為了絕對清楚,這是一個Dictionary<DateTime, Double>還是一個Dictionary<SomeKeyType, IEnumerable<KeyValuePair<DateTime, Double>>> 如果是后者,那么也許你在其他地方持有引用?

你的緩存有多大? 你有監控來跟蹤它嗎? 是什么讓你覺得這是導致問題的字典? 如果您可以控制緩存的數量,那么您是否嘗試過縮小尺寸?

既然你問為什么GC沒有救你,我會給出答案。

使用帶有垃圾收集器的編程語言/環境可以讓您更輕松,但不會使內存管理成為過去。

如果你在32位xp機器中分配大量內存大約2 gig,那么你只需要到達第一個.Net內存邊界之一。 在內存中保持2演出總是一個壞主意。

在運行大型數據庫等的內存受限的機器上,您將很快達到可用內存的邊界。 由於GC不能識別操作系統,因此它可能會注意到內存不足的情況(創建像位圖這樣的巨大對象可能會觸發這種情況)。 一旦你設置了一個巨大的對象,沒有任何幫助,手動調用GC.Collect。

在內存中保存一本大詞典是一個非常簡單的描述。 你能告訴我們這個系列中有什么東西,理論上這些東西有多大。

如果你的意思是2,147,483,647項,你可能會達到整數大小限制。

總結一下:

  • 不要將不需要的項目保留在內存中或將它們交換到磁盤。
  • 一旦你釋放了'大'項目就調用GC.Collect(但是在循環之后不要在循環中刪除項目)

我不確定,對不起我,如果我錯了,但也許當大於85kB時字典存儲在大對象堆中(如字節[90000])

像加布賽義德一樣:

我可以看到,大型對象堆可能會碎片化,並且您無法在一個點之后增長字典

當LOH被分割時,它有時沒有足夠的空間來存儲帶有contigus地址的對象。 這就是造成OutOfMemory異常的原因。 它更像是LOH異常中的Out Of Contigus空間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM