2014-03-26 84 views
0

我有大約16000個節點的大型數據集。對於每個節點,我基於一些相似性度量來找到k個最近鄰居。前k個鄰居駐留在一個優先隊列中(自我實現)。隨着仿真的進行(爲所有鄰居計算knn),內存使用量不斷增加,仿真速度變慢。如果我想在刪除先前用戶的優先隊列時釋放內存,我該怎麼做?這是唯一可能的原因,還是可能有其他原因導致性能下降?ruby​​中的內存分配

+0

Ruby不會垃圾收集仍然從某處引用的對象。如果要清除內存,則需要將所有對所有要刪除的數據結構的引用歸零(分配'nil'或delete)。 – Casper

回答

1

如果你讓你的隊列中成長,那麼你平時應設計縮小它的一些方法了。

你稱你的結構爲'隊列'。所以我假設一些元素流入(即添加到數組中),並且一些元素流出。當他們流出時,他們做什麼?你從隊列中刪除它們嗎?你是否nil - 當它們從隊列中移除時,它們的變量或它們的特定數組單元格?當許多舊元素被殺死後,你是否縮小陣列?

如果你是,那麼它應該沒問題。

Ruby有一個GC,所以每個「丟失」的對象都應該在某個時間點被自動刪除。注意'應該'和'在某個時刻'。很難說清楚什麼時候。如果你有很多空閒的內存,那麼GC可能還沒有運行。嘗試手動踢它,看看內存使用情況是否下降。

如果你不刪除舊的條目,那麼它永遠不會好。直到你實際排隊忘記這些對象,對象纔會保持活躍狀態​​並佔據內存。往上看。

如果你只是nil -ing他們,你永遠不會縮小或重新使用數組中的舊空間,那麼GC將掃除分離的舊對象,但仍然會隨着時間的推移你的陣列會增長。擁有1000000個元素的數組並不明智,其中999900個爲nilSplice這個數組,或者將它複製到一個更小的,或者其他的。並調整你的算法,因爲索引的生活元素會改變。

當然還有一種情況 - 你正在做的一切都正常,GC作品,丟失的物體被刪除。這可能是因爲隊列中的元素不是足夠快速地處理和移除,所以隊列只是增長到了很大的尺寸。例如,您添加1000個新元素/秒,並且工作線程移除10個元素/秒。一小時之後,即使一切工作正常,您都會有一個不錯的(並且在不斷增長)積壓。好。你明白了。這是不容易解決的,你必須仔細檢查並糾正你的整個設計。

例如,對於快速修補程序,可能會:

  • 簡單:確保處理速度較快,所以隊列清空更快
  • 強制限制隊列的長度,即得。 1000個元素,並且使隊列拒絕任何嘗試添加更多(即,引發異常)
  • 強制限制隊列的長度,即。 1000個元素,並靜靜地自動刪除最不重要的元素。這可能有一些缺點:
    • 沒有人知道他們沒有處理
    • 仍然可以是相同的重要性1001+的元素,然後呢?很難決定什麼下降,否則「限價」將是微弱的,保證沒有

但這些只是暗示。在這種情況下,你必須自己重新思考,因爲只有你知道確切需求的重要部分,才能決定你能做什麼以及不能忘記什麼。