.NET 中 GC 的模式与风格
垃圾回收(GC)是托管语言必备的技术之一。GC 的性能是影响托管语言性能的关键。我们的 .NET 既能写桌面程序 (WINFROM , WPF) 又能写 web 程序 (ASP.NET CORE),甚至还能写移动端程序。。。不同使用场景的程序对 GC 的风格也有不同的要求,比如桌面程序更注重界面的响应速度,web 程序注重的是吞吐量。有幸的是 CLR 为我们提供了2种不同的 GC 模式与风格。
Workstation GC
工作站模式被设计为客户端(桌面)程序使用,或者某些只有1个核心的机器使用。工作站模式下 GC 的回收频次会加快,但是每一次 GC 造成的停顿很短暂。工作站模式的垃圾回收直接发生在触发垃圾回收的用户线程上。所以垃圾回收线程需要跟其他用户线程去竞争 CPU 时间。工作站模式下只会分配一个 GC 堆,在工作站模式下 GC 分配的内存会更少。
Server GC
服务器模式适合大型的服务端应用,比如 ASP.NET Core 程序。服务器模式下 GC 的回收会尽量的延迟,从而减少停顿。为了获得更高的吞吐量与性能,程序会分配更多的内存。服务器模式下 CLR 根据 CPU 核心数量来分配 GC 堆的数量。同时为每个 GC 堆分配一个专用线程来执行回收,并且这个线程的优先级为 THREAD_PRIORITY_HIGHEST ,所以在与普通线程竞争的时候更容易获得 CPU 时间。服务器模式通常具有更大容量的内存分段。分段容量的大小不是固定的,它跟 OS,逻辑 CPU 数量有关系:

设置使用 workstation 或者 server 模式
根据微软的文档上写的客户端单机程序默认的GC模式是 workstation ,ASP.NET 的 GC 模式取决于主机。如果不清楚默认的 GC 工作模式可以直接指定模式。
在不同的 .NET 版本下有不同的设置方式,参见下图:

我们上面说的 workstation 模式跟 server 模式是 GC 的两个主要模式。而 GC 在这两个模式之下还有两个不同的子风格 Non-Concurrent 跟 Background (concurrent) 风格。
Non-Concurrent
根据 CLR 之前的设计,如果 GC 线程启动那么所有其他的线程都会挂起。

回收 0代、1代这种短代(ephemeral generations)速度是非常快,但是回收2代垃圾对象就相对比较慢。如果线程一直挂起会对程序的响应造成比较大的影响。于是 CLR 设计了 background(concurrent) GC 。 background GC 使用专用线程来回收2代对象,并且回收的时候不会挂起其他线程。
Background
在 background(concurrent) GC 回收执行的时候,0,1代的回收可以同步进行。background(concurrent) GC 使用一个或者多个专用线程来执行回收动作。
在 .NET Framework 4 之前称之为 concurrent GC ,之后称之为 background GC 。在 .NET Framework 4 时代,background GC 只支持在 workstation GC 模式下开启。从 .NET Framework 4.5 开始 background GC 同时支持 workstation , server 模式。以下不再区分 background 跟 concurrent GC,统一使用 background 来描述。
background GC 运行的时候并不会挂起其他线程,但是反过来如果 1,2 代的 GC 正在运行那么会挂起其他所有的线程,包括 background 专用线程。
background GC 在 workstation 跟 server 模式下有一些区别:
in workstation mode
在 workstation 模式下 background GC 使用一个专用线程。

通过上图我们可以看到:THREAD 1 发生 GC 的时候 其他线程包括 background GC 线程都会暂停。而 GC THREAD (background)启动的时候则不会挂起其他线程,而且 GC THREAD 线程只有一个 。
in server mode
在 server 模式下 background GC 会使用多个专用线程。线程的数量取决于逻辑处理器的数量。与在 workstation 模式下不同,server 模式下的 background GC 线程不会超时。

上图中 GC THREAD1、2 代表 FGC 线程,它执行的时候会挂起其他所有的线程包括 BGC 线程。图中的 BGC THREAD1、2 代表专用 background GC 线程。可以看到它执行的时候不会挂起其他线程,而且线程的数量并不是唯一的。
开启关闭 background GC
根据微软的文档说明,在 Server 模式下,background 是默认的 GC 风格。也可以直接通过配置开启 background GC 。
在不同的 .NET 版本下有不同的配置方式,参见下图:

总结
通过以上我们对 GC 的 workstation / server 模式,以及 no-concurrent 跟 background GC 风格有了一定的了解。总结一下:如果你的程序是个客户端程序需要 UI 更快的响应,希望 GC 造成的用户线程暂停时间更短那么选用 workstation 模式。如果你的电脑只有一个处理器那么也选择 workstation 模式。如果你的程序是大型 web 服务,你希望尽可能的利用服务器 CPU 与内存从而获得更大的吞吐量与性能,那么选用 server 模式。在 server 模式下我们也应该尽量使用 background GC 。因为它可以更加充分的利用的多核处理器的优势来进行 GC 操作。
参考
workstation-server-gc
wbackground-gc
fundamentals-gc
CLR 的 GC 工作模式介绍
understanding-different-gc-modes-with-concurrency-visualizer
关注我的公众号一起玩转技术

.NET 中 GC 的模式与风格的更多相关文章
- (转)MVC中的Repository模式
1.首先创建一个空的MVC3应用程序,命名为MyRepository.Web,解决方案命名为MyRepository. 2.添加一个类库项目,命名为MyRepository.DAL,添加一个文件夹命名 ...
- MVC中的Repository模式
1.首先创建一个空的MVC3应用程序,命名为MyRepository.Web,解决方案命名为MyRepository. 2.添加一个类库项目,命名为MyRepository.DAL,添加一个文件夹命名 ...
- 讨论.NET Core 配置对GC 工作模式与内存的影响
引出问题: Asp.net core应用在 Kubernetes上内存使用率过高问题分析 https://mp.weixin.qq.com/s/PqhUzvFpzopU7rVRgdy7eg 这篇文章中 ...
- .NET Core 配置GC工作模式与内存的影响
.NET Core 配置GC工作模式与内存的影响 .NET Core GC 原文:https://blog.markvincze.com/troubleshooting-high-memory-usa ...
- [转]改善C#程序的建议4:C#中标准Dispose模式的实现
需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不 ...
- .Net Core 中GC的工作原理
前言 .NET 中GC管理你服务的内存分配和释放,GC是运行公共语言运行时(CLR Common Language Runtime)中,GC可以帮助开发人员有效的分配内存和和释放内存,大多数情况下是不 ...
- CLR的GC工作模式介绍(Workstation和Server)
CLR的核心功能之一就是垃圾回收(garbage collection),关于GC的基本概念本文不在赘述.这里主要针对GC的两种工作模式展开讨论和研究. Workstaction模式介绍 该模式设计的 ...
- PerfView专题 (第六篇):如何洞察 C# 中 GC 的变化
一:背景 在洞察 GC 方面,我觉得市面上没有任何一款工具可以和 PerfView 相提并论,这也是为什么我会在 WinDbg 之外还要学习这么一款工具的原因,这篇我们先简单聊聊 PerfView 到 ...
- 制作类似ThinkPHP框架中的PATHINFO模式功能
一.PATHINFO功能简述 搞PHP的都知道ThinkPHP是一个免费开源的轻量级PHP框架,虽说轻量但它的功能却很强大.这也是我接触学习的第一个框架.TP框架中的URL默认模式即是PathInfo ...
随机推荐
- 介绍一下 WebApplicationContext?
WebApplicationContext 是 ApplicationContext 的扩展.它具有 Web 应用 程序所需的一些额外功能.它与普通的 ApplicationContext 在解析主题 ...
- 学习Kvm(二)
一.走进云计算 云计算:云计算是一种按使用量付费的模式,这种模式提供可用的.便捷的.按需的网络访问, 进入可配置的计算资源共享池(资源包括网络,服务器,存储,应用软件,服务),这些资源能够被快速提供, ...
- Visual Studio App Center 中的 Bug 跟踪服务
我在之前的一篇文章 <使用 Visual Studio App Center 持续监视应用使用情况和问题> 中介绍了 App Center 的基本功能及使用入门,其中 诊断 可以自动手机用 ...
- 攻防世界NewsCenter
NewsCenter 打开题目是一个搜索框我们首先尝试一下sql注入 判断了一下是使用''进行包裹的字符型sql注入 然后我们需要判断数据库列数 1' order by 3# 回显正常但by4的时候回 ...
- mpvue打包没有app.json等配置文件的解决方法
问题 一早上折腾了1个小时,小程序始终提示查找不到'app.json'文件.mpvue重新打包,光生成内容文件无配置文件. 解决办法 出错原因:版本问题 只需要把packpage.json里的mpvu ...
- ES6-11学习笔记--Reflect
Reflect 映射 将Object属于语言内部的方法放到Reflect上 修改某些Object方法的返回结果,让其变得更合理 让Object操作编程函数行为 Reflect对象的方法与Proxy对象 ...
- 记一次曲折的CVE-2018-1270复现分析
前言 前两天接到朋友对某个授权目标的漏扫结果,也算是初次接触到这个漏洞,就想着顺手分析一下复现一下,因为分析这个漏洞的文章也比较少,所以刚开始比较迷,进度也比较慢. 漏洞复现 使用vulhub搭建环境 ...
- AS之AlertDialog使用
关于AlertDialog的使用,主要是去做一个弹窗. import android.content.DialogInterface; import android.os.Bundle; import ...
- CCF201712-2游戏
问题描述 有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,--,1号小朋友坐在n号小朋友的顺时针方向. 游戏开始,从1号小朋 ...
- script标签中defer和async的区别(稀土掘金学习)
如果没有defer或async属性,浏览器会立即加载并执行相应的脚本.它不会等待后续加载的文档元素,读取到就会开始加载和执行,这样就阻塞了后续文档的加载. 下图可以直观的看出三者之间的区别: 其中蓝色 ...