.Net Core 中GC的工做原理

前言

.NET 中GC管理你服務的內存分配和釋放,GC是運行公共語言運行時(CLR Common Language Runtime)中,GC能夠幫助開發人員有效的分配內存和和釋放內存,大多數狀況下是不須要去擔憂的,可是有時候服務老是是出現莫名的問題,因此仍是有必要了解一下GC的基礎知識的。這裏就不介紹內存方面的知識了。html

GC回收過程

GC將對象分爲大對象和小對象,若是對象的大小大於或者等於85000byte將被視爲大對象,大對象會被分配到到(LOH) Large Object Heap中去。json

GC有一個代數的概念Generation,分爲三代服務器

20200623172623

  • Generation 0: 0代,這裏面都是生命週期很短的對象,好比臨時變量,當你new一個對象的時候該對象都會在Generation 0中,這裏的對象將很快的被GC回收,可是當你new的是一個大對象的時候它會直接進去大對象堆(LOH)併發

  • Generation 1: 1代,這一代包含的也基本是生命週期很短的對象。它是短時間對象和長期對象之間的緩衝區。性能

  • Generation 2: 2代,這一代包含的都是生命週期長的對象,它們都是從1代和2代中選拔出來的,LOH屬於2代。spa

當分配的對象使用的內存超出了GC的閾值時回收就會開始。閾值是隨着服務的運行GC本身調整的。或者直接調用GC.Collect方法也能夠開始回收。線程

回收開始時GC會開始循環遍歷Generation 0中的全部對象並標記全部對象是活動對象仍是非活動對象,標記完成後會更新活動對象的引用。最後會回收非活動對象佔用的內存,並把活動對象壓縮後移動到Generation 1中,Generation 1中的或對象在移動到Generation 2是默認不會被壓縮的,由於複製大的對象會致使性能的降低。能夠經過GCSettings.LargeObjectHeapCompactionMode來配置壓縮LOH3d

GC的回收類型

GC 回收有兩種類型,WorkStation GC(工做站)和Server GC(服務器),.Net Core服務默認狀況下時使用WorkStation GC工做站模式來回收。code

  • Server GC會擁有更大的內存,Server GC會爲每一個處理器建立一個用於執行垃圾回收的堆和專用線程,每一個堆都擁有一個小對象堆和大對象堆,而且全部的堆均可以訪問。 不一樣堆上的對象能夠相互引用。由於多個垃圾回收線程一塊兒工做,因此對於相同大小的堆Server GC垃圾回收比WorkStation GC垃圾回收更快一些。可是Server GC回收會佔用大量資源,這種模式的特色是初始分配的內存較大,而且儘量不回收內存,進行回收用時會很耗時,並進行內存碎片整理工做。htm

  • Workstation GC的內存相對於Server GC就很小啦,且它的回收線程就是服務的線程且有較高的優先級,由於必須與其餘線程競爭 CPU 時間來進行回收。

不一樣模式下的內存分配
20200623154852

GC的回收模式

GC有三種回收模式

  • Non-Concurrent GC 非並行回收模式:在非並行模式下,回收時候會掛起全部其餘的線程影響服務的性能。

  • Concurrent GC 並行回收模式: 並行會後能夠解決非並行回收引發的線程掛起,讓其餘線程和回收線程一塊兒運行,使服務能夠更快的響應,並行回收只會發生在Generation 2中,Generation 0/1始終都是非併發的,由於他們都是小對象回收的速度很快。在並行回收的時候咱們依舊能夠分配對象到Generation 0/1中。

  • Background GC 後臺回收模式:Background GCConcurrent GC的加強版本。 區別在Background GC回收Generation 2的時容許了Generation 0/1 進行清理。在WorkStation GC下會使用一個專用的後臺垃圾回收線程,而Server GC下會使用多個線程來進行回收。且Server GC下回收線程不會超時。

非並行回收:
20200623143747

並行回收
20200623170251

WorkStation GC 後臺回收
20200623145944

Server GC 後臺回收
20200623150013

GC回收類型配置

推薦使用runtimeconfig.json文件和環境變量COMPlus_gcServer來配置。

COMPlus_gcServer 0 = WorkStation GC
COMPlus_gcServer 1 = Server GC

{
   "runtimeOptions": {
      "configProperties": {
         "System.GC.Server": true 
         //true - Server GC  false - WorkStation GC
      }
   }
}

GC回收模式配置

推薦使用runtimeconfig.json文件和環境變量COMPlus_gcConcurrent來配置。

COMPlus_gcConcurrent 0 =Non-Concurrent GC
COMPlus_gcConcurrent 1 =Background GC

{
   "runtimeOptions": {
      "configProperties": {
         "System.GC.Concurrent": true 
         //true- Background GC false -Non-Concurrent GC
      }
   }
}

強制回收

在一些特殊的狀況下強制回收是能夠提升服務的性能的,能夠向GC.Collect()提供GCCollectionMode枚舉值觸發強制回收。

  • Default :默認的回收設置。
  • Forced :當即強制進行垃圾回收。
  • Optimized : GC來判斷時間是不是回收對象的最佳時間,如GC斷定回收效率不高所以回收不合理的狀況下將返回不回收對象。
GC.Collect( (int) GCCollectionMode.Forced);

延遲迴收

在咱們的服務在檢索數據或者處理邏輯的時候可能會發生垃圾回收,從而妨礙性能,能夠經過System.Runtime.GCLatencyMode來配置延遲迴收

  • GCLatencyMode.LowLatency:禁止Generation 2回收,只回收Generation 0/1,這個只能在短期內使用,若是長時間使用內存處於壓力下GC仍是會觸發回收,這個配置只對WorkStation GC可用。

  • GCLatencyMode.SustainedLowLatency :禁止Generation 2 Foreground GC (前臺回收),只回收Generation 0/1Generation 2後臺回收。WorkStation GCServer GC均可以使用,且能夠長時間使用,可是若是禁用Background GC,將沒法使用。

GC.Collect( (int) GCLatencyMode.SustainedLowLatency);

參考文章

從ASP.NET Core 3.0 preview 特性,瞭解CLR的Garbage Collection

微軟文檔

總結

參考了一些大佬和官方的文檔簡單的去了解了一下GC的工做原理,方便在開發中有效區分配使用內存資源,文中若有錯誤大佬們能夠在評論區指出。

相關文章
相關標籤/搜索