.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 - 后台 GCfalse - 非並發 GC |
.NET Core 1.0 |
MSBuild 屬性 | ConcurrentGarbageCollection |
true - 后台 GCfalse - 非並發 GC |
.NET Core 1.0 |
環境變量 | COMPlus_gcConcurrent |
1 - 后台 GC0 - 非並發 GC |
.NET Core 1.0 |
環境變量 | DOTNET_gcConcurrent |
1 - 后台 GC0 - 非並發 GC |
.NET 6 |
.NET Framework 的 app.config | gcConcurrent | true - 后台 GCfalse - 非並發 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}");// 工作方式