【C# .Net GC】GC的類型與工作方式 和配置


 

.net主要有兩種類型垃圾回收器,也可也說是垃圾回收器的兩種工作模式。

GC的類型主要有兩種;

工作模式是針對進程的,程序啟動后就不能修改了。只能在配置文件.json .xml進行設置。但是可用通過GCSeting類的GCLatencyMode進行微調(也叫延遲模式)。

  • 工作站(默認的.NET程序都是WorkStation GC)
  • 服務器 (默認的.NET程序都是WorkStation GC)

GC的工作方式主要有兩種

每種類型都對應兩種工作方式

  • 后台(.net4.0后用后台模式取代並發模式)
  • 非並發

 

工作站和服務器垃圾回收

使用條件:進程終止前不會改變,不過可用通過GCsetting類的GClatencyMode進行控制。

工作站
該模式針對客戶端應用程序優化GC.GC造成的延時很低,應用程序線程掛起時間很短,避免使用戶感到焦慮。在該模式中,GC假定機器上運行的其他應用程序都不會消耗太多的CPU資源。

工作站垃圾回收既可以是並發的,也可以是非並發的。 並發(或后台 )垃圾回收使托管線程能夠在垃圾回收期間繼續操作。 后台垃圾回收替換 .NET Framework 4 及更高版本中的並行垃圾回收
服務器
該模式針對服務器端應用程序優化GC。被優化的主要是吞吐量資源利用。GC假定機器上沒有運行其他應用程序(無論客戶端還是服務器應用程序),並假定機器的所有CPU都可用來輔助完成GC。該模式造成托管堆被拆分成幾個區域(section),每個CPU一個。開始垃圾回收時,垃圾回收器在每個CPU上都運行一個特殊線程;每個線程都和其他線程並發回收它自己的區域。對於工作者線程(worker thread)行為一致的服務器應用程序,並發回收能很好地進行。這個功能要求應用程序在多CPU計算機上運行,使線程能真正地同時工作,從而獲得性能的提升。

  • 在 .NET Core 中,服務器垃圾回收既可以是非並發也可以是后台執行。

  • 在 .NET Framework 4.5 和更高版本中,服務器垃圾回收既可以是非並發也可以是后台執行。 在 .NET Framework 4 和以前的版本中,服務器垃圾回收非並行運行

 

應用程序默認以“工作站”GC模式運行。寄宿了CLR的服務器應用程序(比如ASP.NET或Microsoft SQL Server)可請求CLR加載“服務器”GC.但如果服務器應用程序在單處理器計算機上運行,CLR將總是使用“工作站"GC模式。

獨立應用程序可創建一個配置文件告訴CLR使用服務器回收器。配置文件要為應用程序添加一個gcServer元素。下面是一個示例配置文件:

.net core 在.csproj 文件中添加

<PropertyGroup>
  <ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>

 

.net frame

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

應用程序運行時,可查詢GCSettings類的只讀Boolean屬性IsServerGC來詢問CLR它是否正在“服務器”GC模式中運行:

using System;  
using System.Runtime; // GCSettings is in this namespace  
  
public static class Program {  
   public static void Main() {   
      Console.WriteLine("Application is running with server GC=" + GCSettings.IsServerGC);   
    }   
}

 

除了這兩種主要模式,GC還支持兩種子模式:並發(默認)或非並發。

在並發方式中,垃圾回收器有一個額外的后台線程,它能在應用程序運行時並發標記對象。一個線程因為分配對象造成第0代超出預算時,GC首先掛起所有線程,再判斷要回收哪些代。
事實上,垃圾回收器更傾向於選擇不壓縮。可用內存多,垃圾回收器便不會壓縮堆;這有利於增強性能,但會增大應用程序的工作集。

為了告訴CLR不要使用並發回收器,可創建包含geConcurrent元素的應用程序配置文件。下面是配置文件的一個例子:

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

 

配置

后台/非並發配置

  • 配置是否啟用后台(並發)垃圾回收。
  • 默認:使用后台垃圾回收。 它等效於將值設置為 true
  • 有關詳細信息,請參閱后台垃圾回收
后台垃圾回收
  設置名 引入的版本
runtimeconfig.json System.GC.Concurrent true - 后台 GC
false - 非並發 GC
.NET Core 1.0
MSBuild 屬性 ConcurrentGarbageCollection true - 后台 GC
false - 非並發 GC
.NET Core 1.0
環境變量 COMPlus_gcConcurrent 1 - 后台 GC
0 - 非並發 GC
.NET Core 1.0
環境變量 DOTNET_gcConcurrent 1 - 后台 GC
0 - 非並發 GC
.NET 6
.NET Framework 的 app.config gcConcurrent true - 后台 GC
false - 非並發 GC

 

示例

runtimeconfig.json 文件:

{
   "runtimeOptions": { "configProperties": { "System.GC.Concurrent": false } } }

項目文件:

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <ConcurrentGarbageCollection>false</ConcurrentGarbageCollection> </PropertyGroup> </Project>

 案例 .net6.0 C#10

using System.Runtime;
//查看GC的初始配置:類型、工作方式以及微調工作方式。  類型、工作方式在.json或xml文件中修改。不過可用在程序運行時候微調
Console.WriteLine($"IsServerGC:{GCSettings.IsServerGC}");// 釋放是服務器GC
Console.WriteLine($"IsConcurrent:{System.GC.GetGCMemoryInfo().Concurrent}");//工作方式 System.GC  
Console.WriteLine($"LatencyMode:{GCSettings.LatencyMode}");// 微調工作方式狀態

Console.WriteLine("GC的工作方式進行微調 將默認的模式修改成Batch");
GCLatencyMode oldGCL=GCSettings.LatencyMode;//獲取單曲的GC
try
{
    GCSettings.LatencyMode = GCLatencyMode.Batch;
    //要執行其他代碼
}
finally 
{
    //修改回去
    GCSettings.LatencyMode=oldGCL;
}
GCSettings.LatencyMode = GCLatencyMode.Batch;
Console.WriteLine($"IsConcurrent:{System.GC.GetGCMemoryInfo().Concurrent}");// //System.GC
Console.WriteLine($"LatencyMode:{GCSettings.LatencyMode}");// 工作方式

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM