2012-07-23 53 views
8

我正在做一個關於.net CLR GC的介紹性演示文稿,並且有各種各樣的部分,但我想具體說明如何強制收集可能是危險的或有害的。我知道你可以過早強迫某些事情進入更高層次的世代,但是(從我所知道的情況來看)這隻會讓事情慢下來。強制GC變壞的例子?

我試圖想到一種情況,迫使GC可能是真正的破壞性,我不斷提出瓦/只是效率較低的解決方案。

+2

時間損失是唯一的缺點。 – Dialecticus 2012-07-23 19:57:43

+0

通過「強制收集」我假定你的意思是通過調用GC.Collect()。你爲什麼會認爲這會很危險?是否有一些我錯過的文檔說明了這一點? (我意識到可能性很高,因爲我無法跟上這些日子。) – David 2012-07-23 19:58:01

+0

有實時要求的緊時間可能嗎? – leppie 2012-07-23 19:58:07

回答

4

這是一個有趣的演示。請注意,您應該運行在發佈模式下編譯的演示程序,否則它可能無法正常播放。

版本1:

private void Button_Click(object sender, EventArgs e) 
{ 
    Timer timer = new Timer(Print, null, 0, 1000); 
} 

private void Print(Object o) 
{ 
    if (textBox1.InvokeRequired) 
    { 
     Action<object> action = Print; 
     textBox1.Invoke(action, o); 
     return; 
    } 

    textBox1.Text = DateTime.Now.ToString(); 
} 

1版會很樂意打印日期和時間文本框一次第二。

版本2:

private void Button_Click(object sender, EventArgs e) 
{ 
    Timer timer = new Timer(Print, null, 0, 1000); 
} 

private void Print(Object o) 
{ 
    if (textBox1.InvokeRequired) 
    { 
     Action<object> action = Print; 
     textBox1.Invoke(action, o); 
     return; 
    } 

    textBox1.Text = DateTime.Now.ToString(); 

    GC.Collect(); // force a garbage collection 
} 

現在,在第2版,日期和時間將只因爲,在聲明之後,有到計時器對象的更多引用打印一次,所以計時器對象獲得集。

這是一個相當人爲的例子,但可能是一個很好的示範。

我必須相信傑弗裏裏希特這一個 - 這是在他的優秀書CLR via C#

+0

我相信如果您只是調用'new Timer(...'並且不保存返回值,那麼這種行爲會更加出乎意料。 – 2012-07-23 20:36:09

+2

但是在這種情況下,'GC.Collect()'並不壞,它確實很好,因爲它幫助你發現應用程序中的一個錯誤。如果沒有'GC.Collect()',它會在未來一段時間神祕地停止工作。 – svick 2012-07-23 23:29:19

+0

@svick - 好點。也許這只是一個關於範圍界定的更好的教訓。無論如何,這很有趣,它讓人想到GC。 – James 2012-07-23 23:59:25

1

以下情況如何,壞主意? 「讓我們在ASP.NET中的每個HTTP請求之後強制執行一次GC,以清理將肯定會成爲孤兒的請求狀態!」

這是一個壞主意,因爲併發HTTP請求會互相干擾。這會引入很多延遲峯值並破壞性能。所有這些從無辜的「優化」開始。

這是我能想到的最糟糕的事情。