使用 GC.Collect() 有什麼問題?
儘管我確實理解使用此功能的嚴重影響(或者至少我是這麼認為的),但我不明白為什麼它會成為受人尊敬的程序員永遠不會使用的東西之一,即使是那些甚至不知道的人它是乾什麼用的。
假設我正在開發一個應用程序,其中記憶體使用量根據使用者的操作而變化很大。應用程序生命週期可以分為兩個主要階段:編輯和實時處理。在編輯階段,假設創建了數十億甚至數万億個對象;其中有些很小,有些沒有,有些可能有終結器,有些可能沒有,假設它們的生命週期從幾毫秒到幾小時不等。接下來,使用者決定切換到實時階段。在這一點上,假設性能起著根本性的作用,並且程序流程中最輕微的改變都可能帶來災難性的後果。然後,通過使用對像池等將對象創建減少到最低限度,但隨後,GC 意外啟動並將其全部扔掉,有人死了。
問題:在這種情況下,在進入第二階段之前呼叫 GC.Collect() 不是明智的嗎?
畢竟,這兩個階段在時間上永遠不會重疊,GC 可能收集的所有優化和統計資訊在這裡都沒什麼用……
注意:正如你們中的一些人所指出的,.NET 可能不是這樣的應用程序的最佳平台,但這超出了這個問題的範圍。目的是澄清 GC.Collect() 呼叫是否可以改善應用程序的整體行為/性能。我們都同意你會做這樣的事情的情況是非常罕見的,但話又說回來,GC 試圖猜測並且大部分時間都做得很好,但它仍然是猜測。
謝謝。
規則1
別。
這確實是最重要的規則。公平地說,GC.Collect() 的大多數用法都是一個壞主意,我在原始文章中詳細介紹了這一點,所以我不會在這裡重複所有這些。那麼讓我們繼續…
規則 #2
如果某個非重複事件剛剛發生並且該事件很可能導致許多舊對象死亡,請考慮呼叫 GC.Collect()。
一個典型的例子是,如果您正在編寫一個客戶端應用程序,並且您顯示一個非常大且複雜的表單,其中包含大量相關數據。您的使用者剛剛與此表單進行了互動,可能會創建一些大型對象……諸如 XML 文件或一兩個大型 DataSet 之類的東西。當表單關閉時,這些對像已死,因此 GC.Collect() 將回收與它們關聯的記憶體……
所以聽起來這種情況可能屬於第 2 條規則,你知道有一段時間很多舊對像已經死亡,而且它不會重複出現。但是,不要忘記 Rico 的離別詞。
在沒有強有力證據的情況下,規則 #1 應該勝過規則 #2。
測量,測量,測量。