什麼觸發了 gen2 垃圾回收?
我有一個奇怪的情況,我想弄清楚。
創世紀:
我在具有16 個核心和128GB RAM 的物理機器上執行我的程序。我試圖確定為什麼它沒有使用所有可用的核心,通常它平均使用 20-25% 的 CPU(所以 16 個核心中有 4-5 個)。當我查看性能計數器時,它們顯示的垃圾收集時間大約為 60-70%。
作為參考,我使用 .NET Framework 4 和 TPL (Parallel.ForEach) 來處理我的程序的性能密集型部分。我將執行緒數限制為核心數。
問題:
我正在創建大量對象,對於垃圾收集器來說太多了,無法有效處理,因此它在垃圾收集器中花費了大量時間。
到目前為止的簡單解決方案:
我正在引入對像池以減少垃圾收集器的壓力。我將繼續池化對像以提高性能,已經將一些對像池化將垃圾收集的時間從 60-70% 減少到 45%,並且我的程序執行速度提高了 40%。
嘮叨的問題(我希望你能回答我的問題):
我的程序在執行時最多使用 14GB 的可用 RAM,與 128GB 的 RAM 相比,這是相當小的。這台機器上沒有執行其他任何東西(對我來說它純粹是一個測試平台)並且有大量可用的 RAM。
- 如果有足夠的 RAM 可用,為什麼會發生任何 gen2(或完整)集合?相當大量的這些 gen2 集合(數以千計)正在發生。即如何確定開始 gen2 收集的門檻值?
- 為什麼垃圾收集器不簡單地延遲任何完整的收集,直到物理 RAM 上的壓力達到更高的門檻值?
- 有什麼辦法可以配置垃圾收集器等待更高的門檻值?(即如果沒有必要,根本不用費心收集)
編輯:
我已經在使用使用伺服器垃圾收集器的選項……我需要知道的是什麼觸發了 gen2 收集,而不是伺服器垃圾收集器更好(我已經知道了)。
我記得,客戶端 GC 是預設設置。我的經驗是它不會讓堆在收集之前變得非常大。對於我的重型處理應用程序,我使用“伺服器”GC。
在應用程序配置文件中啟用伺服器 GC:
<?xml version ="1.0"?> <configuration> <runtime> <gcServer enabled="true"/> </runtime> </configuration>這對我來說在性能上有*很大的不同。*例如,我的一個程序將 80% 以上的時間用於垃圾收集。啟用伺服器 GC 將其降低到略高於 10%。記憶體使用量增加了,因為 GC 讓它消失了,但這對我的大多數應用程序來說都很好。
另一個會導致 Gen 2 收集的事情是大對象堆。請參閱CLR 由內而外:發現大型對象堆。簡而言之,如果您超過 LOH 門檻值,它將觸發 Gen 2 收集。如果您要分配大量短期大對象(大約 85 KB),這將是一個問題。