討論.NET Core 配置對GC 工做模式與內存的影響

引出問題: Asp.net core應用在 Kubernetes上內存使用率太高問題分析

https://mp.weixin.qq.com/s/PqhUzvFpzopU7rVRgdy7eggit

這篇文章中討論了,在默認狀況下,ASP.NET Core程序跑在K8s的Docker中內存使用率>=600MB,致使Docker容器頻繁重啓。並探討並作了將ASP.NET Core項目配置System.GC.Server設置爲False後,內存小於<=150MB的實驗。github

這文主要講下什麼是System.GC.Server,還有GC的二種模式。多線程

對GC工做模式的分類:

.NET Core 兩種GC模式:

Server GC / Workstation GC

Server GC :

主要應用於多處理器系統,而且做爲ASP.NET Core宿主的默認配置。它會爲每一個處理器都建立一個GC Heap,而且會並行執行回收操做。該模式的GC能夠最大化吞吐量和較好的收縮性。這種模式的特色是初始分配的內存較大,而且儘量不回收內存,進行回收用時會很耗時,並進行內存碎片整理工做。併發

Workstation GC :

主要應用於單處理器系統,Workstation GC儘量地經過減小垃圾回收過程當中程序的暫停次數來提升性能。低負載且不常在後臺(如服務)執行任務的應用程序,能夠在禁用併發垃圾回收的狀況下使用工做站垃圾回收。特色是會頻繁回收,來阻止一次較長時間的回收。asp.net

Concurrent GC 工做方式 :

是一種GC的工做方式,若是你是單處理器的機器,那麼即使配置了Concurrent選項爲True,也不會生效。Server GC 和Workstation GC均可以開啓Concurrent GC,在GC回收的過程當中大部分時間用戶線程能夠併發運行。但只能影響到2代對象GC的過程,由於0代1代的時間過短了。性能

5.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、一、2代的對象時,須要向系統申請時的基本單位是Segment,系統會分配指定值大小的Segment用於存儲對象,這些值會隨着程序的實際執行狀況,由GC動態調整。正是因爲有Segment的概念因此回出現內存碎片的問題,因此GC在垃圾回收過程當中會進行內存整理,以減小內存碎片提升內存使用率。優化

Segment的大小取決於系統是32位仍是64位,以及它正在運行的垃圾收集器的類型,下表列出了分配時系統所使用的默認值:.net

GC Model 32-bit 64-bit
Workstation GC 16 MB 256 MB
Server GC 64 MB 4 GB
Server GC with > 4 logical CPUs 32 MB 2 GB
Server GC with > 8 logical CPUs 16 MB 1 GB

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>

特色:多處理器機器上使用多線程處理相同類型的請求以便最大化服務程序吞吐量, GC Heap數量爲每處理器1個,每一個處理器都有一個專職的GC線程,GC線程擁有最高線程的優先級,工做線程(非GC線程)會由於GC工做過程當中會被掛起。

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

推廣

GitHub:https://github.com/maxzhang1985/YOYOFx 若是覺還能夠請Star下, 歡迎一塊兒交流。

.NET Core 開源學習羣:214741894

相關文章
相關標籤/搜索