.NET Core 配置GC工作模式与内存的影响
对GC工作模式
的分类
为了满足不同的内存使用要求,GC 有一些选项来配置其运行方式。有两种主要模式:工作站模式(旨在最小化延迟)和服务器模式(旨在最大应用程序吞吐量)。GC 还支持两种“子模式”之一——并发或非并发
工作站模式
服务器模式
- 并发垃圾回收(.NET Framework 4以上被后台垃圾回收代替)
- 非并发垃圾回收(.NET Framework 4以上被后台垃圾回收代替)
后台垃圾回收
(后台垃圾回收期间对暂时代(0,1代)的回收称为“前台
”垃圾回收, 后台垃圾回收是在一个或多个专用线程上执行的,具体取决于它是工作站还是服务器 GC,它只适用于第 2 代回收)
工作模式:工作站
、服务器
工作方式:后台
、非并发
GC内存分配原则
暂时代:因为第 0 代和第 1 代中的对象的生存期较短,因此,这些代被称为“暂时代”。
暂时段:暂时代在称为“暂时段(段:Segment)”的内存段中进行分配。 垃圾回收器获取的每个新段将成为新的暂时段,并包含在第 0 代垃圾回收中幸存的对象。 旧的暂时段将成为新的第 2 代段。
第 2 代段:保存第二代对象(大对象 以及暂时代的幸存对象)的内存段。
根据系统为 32 位还是 64 位以及它正在哪种类型的垃圾回收器(工作站或服务器 GC)上运行,暂时段的大小发生相应变化。 下表显示了暂时段的默认大小。
Segment的大小取决于系统是32位还是64位,以及它正在运行的垃圾收集器的类型,下表列出了分配时系统所使用的默认值:
GC 类型 | 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 |
从以上表格可知: 工作站GC使用较小的Segment,服务器GC使用较大的Segment
工作站 GC 与服务器 GC
工作站 GC
专为桌面应用程序而设计,可最大程度地减少 GC 所花费的时间。在这种情况下,GC 会更频繁
地发生,但应用程序线程中的暂停时间会更短。该模式支持 并发
和 非并发
两种执行模式(并发执行模式为默认的执行模式, netcore中被"后台GC
"代替),一般适用于客户端程序
服务器 GC
针对应用程序吞吐量进行了优化,有利于更长的 GC 暂停。内存消耗会更高,但应用程序可以处理更大量的数据而不触发垃圾收集。在netcore中也分为后台/前台GC
GC 类型 | GC频率 | GC使用线程 | GC使用线程数 |
---|---|---|---|
工作站GC | 频繁 | 分配对象的线程 | 单线程 |
服务器GC | 不频繁 | 独立线程 | 多线程 |
“并发”或“非并发”等 GC 风格可能有助于微调垃圾收集
,以获得应用程序的最大性能和/或响应能力。并发模式减少了 GC 所花费的总时间,因为第二代的标记阶段发生在与应用程序线程并行的专用线程中。在此模式下,GC 会暂停用户线程较短的时间,但会使用稍多的内存。
用于垃圾回收的运行时配置选项
详细的设置, 参考微软官方文档: https://learn.microsoft.com/zh-cn/dotnet/core/runtime-config/garbage-collector
# runtimeconfig.json
{
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true, # 工作站false, 服务器true
"System.GC.Concurrent": false # 非并发false, 后台(并发)true
}
}
}
# MSBuild 属性
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection> # 工作站false, 服务器true
<ConcurrentGarbageCollection>false</ConcurrentGarbageCollection> # 非并发false, 后台(并发)true
</PropertyGroup>
</Project>
工作站GC
工作站垃圾回收的线程处理和性能注意事项:
-
回收发生在触发垃圾回收的
用户线程上
,并保留相同优先级。 因为用户线程通常以普通优先级运行,所以垃圾回收器(在普通优先级线程上运行)必须与其他线程竞争 CPU 时间。 (运行本机代码的线程不会由于服务器或工作站垃圾回收而挂起。) -
工作站垃圾回收始终用于只有一个逻辑 CPU 的计算机,无论配置设置如何。
服务器GC
从 .NET Framework 4.5 开始,或.net core中,后台垃圾回收可用于服务器 GC。 服务器 GC 是服务器垃圾回收的默认模式。
服务器 GC 以内存换取吞吐量。较大的堆意味着内存饱和发生的频率较低,但一旦发生,CLR 需要做更多的工作来遍历堆。因此,应用程序会消耗更多的内存,GC 发生的频率会降低,但即使是收集 Gen0 和 Gen1,每次 GC 也会花费更长的时间。
服务器垃圾回收的线程处理和性能注意事项:
-
回收发生在多个专用线程上。 在 Windows 上,这些线程以 THREAD_PRIORITY_HIGHEST 优先级运行。
-
为
每个
逻辑 CPU 提供一个用于执行垃圾回收的一个堆和专用线程
,并将同时回收这些堆。 每个堆都包含一个小对象堆和一个大对象堆,并且所有的堆都可由用户代码访问。 不同堆上的对象可以相互引用。 -
因为多个垃圾回收线程一起工作,所以对于相同大小的堆,
服务器垃圾回收比工作站垃圾回收更快一些
。 -
服务器垃圾回收通常具有
更大的段
。 但是,这是通常情况:段大小特定于实现且可能更改。 调整应用程序时,不要假设垃圾回收器分配的段大小。 -
服务器垃圾回收会
占用大量资源
。 例如,假设在一台有 4 个逻辑 CPU 的计算机上,运行着 12 个使用服务器 GC 的进程。 如果所有进程碰巧同时回收垃圾,它们会相互干扰,因为将在同一个逻辑 CPU 上调度 12 个线程。 如果进程处于活动状态,则最好不要让它们都使用服务器 GC。如果运行应用程序的数百个实例
,请考虑使用工作站垃圾回收并禁用并发垃圾回收。 这可以减少上下文切换,从而提高性能。
后台服务器垃圾回收
与后台工作站垃圾回收
具有类似功能
,但有一些不同之处:
- 后台工作站垃圾回收使用
一个专用
的后台垃圾回收线程,而后台服务器垃圾回收使用多个线程
。 通常一个逻辑处理器有一个专用线程。 - 不同于工作站后台垃圾回收线程,这些后台服务器 GC 线程
不会超时
。
常用GC相关的方法和设置
GCSettings.LargeObjectHeapCompactionMode
CompactOnce 下一次阻止第 2 代垃圾回收期间将压缩大型对象堆 (LOH)。
Default 不压缩大型对象堆 (LOH)。
// 指定是否对大对象堆进行压缩,以减少内存碎片
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GCSettings.LatencyMode
参考官方文档
https://learn.microsoft.com/zh-cn/dotnet/api/system.runtime.gclatencymode?view=net-7.0
https://learn.microsoft.com/zh-cn/dotnet/standard/garbage-collection/latency
// 控制GC的延迟模式,以平衡系统的响应性能和内存使用
GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency;
GC.WaitForPendingFinalizers
挂起当前线程,直到处理终结器队列的线程清空该队列为止。
https://learn.microsoft.com/zh-cn/dotnet/api/system.gc.waitforpendingfinalizers?view=net-7.0
// 等待待定的Finalizer方法执行完毕
GC.WaitForPendingFinalizers();
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}");// 微调工作方式状态
扩展阅读
微软官方文档:垃圾回收
.NET 运行时配置设置
【CLR C#】浅谈.Net的GC(垃圾回收)机制及其整体流程
.NET Core 配置GC工作模式与内存的影响
了解不同的 GC 模式
编写高性能.net代码--垃圾回收的前世今生
最后更新于 2023-10-29 23:25:20 并被添加「」标签,已有 651 位童鞋阅读过。
本站使用「署名 4.0 国际」创作共享协议,可自由转载、引用,但需署名作者且注明文章出处
此处评论已关闭