2010-07-16 25 views
4

我的應用程序分析顯示大型垃圾收集開銷。分析器沒有深入到垃圾收集中。我應該怎麼做才能減少這種開銷?如何降低垃圾收集性能開銷

我有很多短命的陣列列表,還有一些只有當應用程序關閉時纔會死的長壽命陣列列表。

+4

顯示您使用'ArrayList'的示例。 – ChaosPandion 2010-07-16 18:05:32

+0

什麼是陣列列表,這個載荷有什麼樣的生命週期? – 2010-07-16 20:00:42

+0

在構造函數中我有new()的4-5數組列表。 然後有一個ApplyLogic(),我在開頭做了一個clear()。 ApplyLogic()調用一些其他函數來填充這些數組列表並將其內容傳遞給套接字,並在ApplyLogic()結束時再次執行clear()以進行下一次迭代。 – bsobaid 2010-07-19 13:25:48

回答

5

如果你有太多的垃圾收集開銷,減少你的垃圾。嘗試重用列表(預先分配並使用它們,完成後清除它們)。

如果您正在使用帶值類型的ArrayList,請嘗試切換爲使用List<T>

+2

他們的算法一定還有其他問題,即使我爲實驗編寫垃圾代碼,我也不必擔心GC。 – ChaosPandion 2010-07-16 18:07:24

+0

當然最有可能的情況下:) – 2010-07-16 18:10:23

+0

@ChaosPandion:當然,除非他們正在(半)非標準平臺上工作。例如,XNA中的XBox360上的GC往往非常頻繁地出現問題... – 2010-07-16 18:15:51

2

如果垃圾收集開銷成爲一個嚴重的性能問題,那麼您必須查看您的設計並重新評估您正在創建的短暫對象的數量。

0

如果此應用程序作爲服務運行,或者在返回用戶界面之前執行大量工作,則可能需要更改垃圾收集模型。

沒有額外的細節,很難給出一個好的建議。

7

基本上你應該減少垃圾收集器的工作。有一些「模式」會產生很多工作。

  • 避免使用多個終結器對象。終結器在垃圾收集器上施加額外的工作,因爲具有終結器的對象必須被收集兩次。
  • 避免'中年'危機。 .NET GC(在桌面上)是世代GC。當物體在第一次收集時倖存下來,但不久之後'死亡',GC就沒有任何事情做了很多工作。 (應付第二代,再收集等)。因此,儘量優化對象的生命週期,讓它們以非常快的速度死亡或長時間存活。
  • 減少不必要的分配。例如明智地使用值類型。或者以較少內存密集的方式完成這項工作。

因此,在你的情況下,我猜你或者是短命列表中的「中年」危機。或者你簡單地分配列表像瘋了一樣。

在第一種情況下:儘量縮短列表的壽命。我無法告訴你該解決方案如何適用於您的應用程序。

在第二種情況下:儘量避免分配這麼多列表。也許你可以使用適當的值類型?還是固定大小的數組?或者改變代碼的結構以減少需要的列表?

無論如何,我會建議您介紹一下您的應用,看看您分配的內存有多少,以及第一代可以收集多少。

+0

短暫的跨度是在函數內創建一個列表new()的地方嗎?因此一旦功能超出範圍,就會超出範圍並有資格收集資源? 或函數的長度也很重要?如果函數很大,即使該函數在函數內實例化,數組列表也可能不會收集到第一代集合中? – bsobaid 2010-07-19 15:08:10

+0

重要的是,如果還有對象的引用。函數的長度幾乎沒有影響。當然,當你有一個真正的長方法時,它首先分配對象,然後做很多其他的工作,同時對象永遠不會超出範圍,它可能將對象移動到第二代。但是隨着你的日常代碼,這應該是一個問題。 – Gamlor 2010-07-20 18:03:02

+0

「重要的是,如果仍然有對象的引用。」 按對象表示由arraylist保存的對象? 是的,該對象仍然存在並超過該功能。 – bsobaid 2010-07-20 21:18:23