2010-09-17 45 views
2

我使用C#3.5和反應延長前4GC.Collect的和C#多線程

我的應用程序在多個地方調用GC.Collect的()(TPL支持在C#中的版本是的,我知道我應該不是手動調用這個方法,但至少這個問題請留下這一點)。在將多線程實現放入之前,它工作正常。在每個線程中調用GC.Collect(),以便在多線程上下文中調用它。

然後我使用任務來實現多線程,我發現應用程序運行一段時間後內存使用量增加,線程停止正常工作。我從多核心計算機上CPU使用率下降到單線程級別的情況聲明「線程停止正常工作」,而不是完全使用。

當我試圖解決這個問題時,我所做的唯一的事情就是將GC.Collect()調用註釋掉,這個改變使線程正常工作。我想關閉GC.Collect(),除非當我在我的應用程序中運行一些很大的東西時,如果沒有GC.Collect(),我會遇到OutOfMemory異常。這是我繼續打電話的原因。

現在任何人都可以解釋爲什麼在使用高內存的機器上的多線程上下文中調用GC.Collect()會導致多線程問題?這一點有沒有相關的理論?非常感謝你的答案。

回答

11

GC.Collect()執行完整垃圾回收會阻塞所有線程。它有一個超載GC.Collect(int),允許您指定收集哪些世代。例如,GC.Collect(0)只會收集第一代。不確定這會解決你的問題,但值得一試。

+0

這是一個快速而有見地的幫助。我會試一試。非常感謝你。 – Steve 2010-09-17 01:27:14

1

正如Kirk所說,集合暫停所有線程。這可能會導致垃圾收集過程中出現延遲。

如果您運行的多核計算機上的應用程序,你可能想嘗試使用服務器GC,以確保您的app.config包含:

<configuration> 
<runtime> 
    <gcServer enabled="true"/> 
</runtime> 
</configuration> 

也可以實現並行GC代替(但我認爲這是默認你的情況,如多核計算機上的桌面應用程序,運行.NET 3.5):

<configuration> 
    <runtime> 
    <gcConcurrent enabled="true" /> 
    </runtime> 
</configuration> 

你可以嘗試ServerGC - 它可能給暫停爲好,但這些暫停可能會更短/更少,並且可能會提供更好的整體吞吐量。 您的里程可能會有所不同。