.NET Core 配置GC工作模式與內存的影響
原文:https://blog.markvincze.com/troubleshooting-high-memory-usage-with-asp-net-core-on-kubernetes/
譯文:https://www.csharpkit.com/2017-11-13_50283.html
對GC工作模式的分類
.NET Core 兩種GC模式:
Server GC / Workstation GC
Server GC :
主要應用於多處理器系統,並且作為ASP.NET Core宿主的默認配置。它會為每個處理器都創建一個GC Heap,並且會並行執行回收操作。該模式的GC可以最大化吞吐量和較好的收縮性。這種模式的特點是初始分配的內存較大,並且盡可能不回收內存,進行回收用時會很耗時,並進行內存碎片整理工作。
Workstation GC :
主要應用於單處理器系統,Workstation GC盡可能地通過減少垃圾回收過程中程序的暫停次數來提高性能。低負載且不常在后台(如服務)執行任務的應用程序,可以在禁用並發垃圾回收的情況下使用工作站垃圾回收。特點是會頻繁回收,來阻止一次較長時間的回收。
Concurrent GC 工作方式 :
是一種GC的工作方式,如果你是單處理器的機器,那么即便配置了Concurrent選項為True,也不會生效。Server GC 和Workstation GC都可以開啟Concurrent GC,在GC回收的過程中大部分時間用戶線程可以並發運行。但只能影響到2代對象GC的過程,因為0代1代的時間太短了。
ASP.NET Core Project GC配置:
ASP.NET CORE項目中,通過System.GC.Server配置進行GC模式設置,創建項目默認的GC模式是: System.GC.Server : true (Server GC Concurrent Mode) 每CPU分配GC ;System.GC.Server : false (Workstation GC Concurrent mode),且Concurrent=1。
GC 內存分配原則:
GC heap用於保存0、1、2代的對象時,需要向系統申請時的基本單位是Segment,系統會分配指定值大小的Segment用於存儲對象,這些值會隨着程序的實際執行情況,由GC動態調整。正是由於有Segment的概念所以回出現內存碎片的問題,所以GC在垃圾回收過程中會進行內存整理,以減少內存碎片提高內存使用率。
Segment的大小取決於系統是32位還是64位,以及它正在運行的垃圾收集器的類型,下表列出了分配時系統所使用的默認值:

Segment包括第2代對象,第2代對象會在內存允許的情況盡可能多的申請到內存,並使用多個段進行內存存儲。
從GC中釋放的內存量僅限於Segment的大小,但由於Segment采用動態大小進行了分配,這就使得釋放后的大量內存占位導致內存使用率低下,前面也說過了,為了解決這個問題GC要對內存碎片進行整理,並中斷所有線程的處理。
.NET Core GC的幾種配置模式:
Concurrent & Workstation GC
<ServerGarbageCollection>false</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
特點:在吞吐量和相應速度上尋找平衡點, GC Heap數量為1,GC threads在分配空間的線程,GC線程優先權和工作線程具有相同的優先權,工作線程(非GC線程)會因為GC工作過程中短暫多次掛起。
Background & Workstation GC
<ServerGarbageCollection>false</ServerGarbageCollection>
<ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>
特點:最大化吞吐量並優化gen2 GC性能, GC Heap數量為1,background GC線程與工作線程有相同優先級,但都低於前台GC線程 ,工作線程(非GC線程)會因為GC工作過程中短暫多次掛起,較並發性能更加(針對Gen2的)。
Concurrent & Server GC
<ServerGarbageCollection>true</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
Background & Server GC
<ServerGarbageCollection>true</ServerGarbageCollection>
<ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>
特點:在Concurrent & Server GC基礎上優化gen2 GC性能, GC Heap數量為每處理器1個,每個處理器都有一個專職的GC background線程,background GC線程與工作線程有相同優先級,但都低於前台GC線程,工作線程(非GC線程)會因為GC工作過程中短暫多次掛起,較並發性能更加(針對Gen2的)
ephemeral generation的前台GC工作時會掛起其他所有線程。
GC幾種模式的分析 (參考資料):
https://blogs.msdn.microsoft.com/seteplia/2017/01/05/understanding-different-gc-modes-with-concurrency-visualizer/
https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals
https://github.com/aspnet/Home/issues/2056