垃圾回收(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 的模式与风格的更多相关文章

  1. (转)MVC中的Repository模式

    1.首先创建一个空的MVC3应用程序,命名为MyRepository.Web,解决方案命名为MyRepository. 2.添加一个类库项目,命名为MyRepository.DAL,添加一个文件夹命名 ...

  2. MVC中的Repository模式

    1.首先创建一个空的MVC3应用程序,命名为MyRepository.Web,解决方案命名为MyRepository. 2.添加一个类库项目,命名为MyRepository.DAL,添加一个文件夹命名 ...

  3. 讨论.NET Core 配置对GC 工作模式与内存的影响

    引出问题: Asp.net core应用在 Kubernetes上内存使用率过高问题分析 https://mp.weixin.qq.com/s/PqhUzvFpzopU7rVRgdy7eg 这篇文章中 ...

  4. .NET Core 配置GC工作模式与内存的影响

    .NET Core 配置GC工作模式与内存的影响 .NET Core GC 原文:https://blog.markvincze.com/troubleshooting-high-memory-usa ...

  5. [转]改善C#程序的建议4:C#中标准Dispose模式的实现

    需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不 ...

  6. .Net Core 中GC的工作原理

    前言 .NET 中GC管理你服务的内存分配和释放,GC是运行公共语言运行时(CLR Common Language Runtime)中,GC可以帮助开发人员有效的分配内存和和释放内存,大多数情况下是不 ...

  7. CLR的GC工作模式介绍(Workstation和Server)

    CLR的核心功能之一就是垃圾回收(garbage collection),关于GC的基本概念本文不在赘述.这里主要针对GC的两种工作模式展开讨论和研究. Workstaction模式介绍 该模式设计的 ...

  8. PerfView专题 (第六篇):如何洞察 C# 中 GC 的变化

    一:背景 在洞察 GC 方面,我觉得市面上没有任何一款工具可以和 PerfView 相提并论,这也是为什么我会在 WinDbg 之外还要学习这么一款工具的原因,这篇我们先简单聊聊 PerfView 到 ...

  9. 制作类似ThinkPHP框架中的PATHINFO模式功能

    一.PATHINFO功能简述 搞PHP的都知道ThinkPHP是一个免费开源的轻量级PHP框架,虽说轻量但它的功能却很强大.这也是我接触学习的第一个框架.TP框架中的URL默认模式即是PathInfo ...

随机推荐

  1. 什么是 spring 装配?

    当 bean 在 Spring 容器中组合在一起时,它被称为装配或 bean 装配.Spring 容器需要知道需要什么 bean 以及容器应该如何使用依赖注入来将 bean 绑定 在一起,同时装配 b ...

  2. nginx 负载均衡详解

    配置文件 upstream abc { server 192.168.2.188:8080 weight=1 max_fails=3 fail_timeout=30; 定义集群,weight=权重轮询 ...

  3. 学习GlusterFS(七)

    初始环境: 系统环境:centos73.10.0-514.26.2.el7.x86_64 机器数量:两台 硬盘:至少两块,一块为系统盘,另一块留作他用 命名规则:node1 node2 IP规划:19 ...

  4. centos 后台 运行jar包方法

    后台运行jar包方法: 1.nohup java -jar shareniu.jar & nohup意为后台不挂断运行,与是否账号退出无关 2.nohup java -jar shareniu ...

  5. vulnhub靶机djinn:1渗透笔记

    djinn:1渗透笔记 靶机下载地址:https://www.vulnhub.com/entry/djinn-1,397/ 信息收集 首先我们嘚确保一点,kali机和靶机处于同一网段,查看kali i ...

  6. 10本 Linux PDF 书籍免费分享

    本篇文章主要分享以下Linux开发PDF书籍 一.Linux程序设计二.Unix环境高级编程三.Unix_Linux编程实践教程四.鸟哥的私房菜五.深入理解Linux内核六.Linux命令行与shel ...

  7. C++“拷贝构造函数”和“等号重载”有什么区别?

    CTypeA(const CTypeB& b)CTypeA& operator=(const CTypeB& b)一直没弄懂这两个有什么区别.只知道,重载了=号,下面复制的时候 ...

  8. HTML5 Canvas绘制效率如何?

    js运行效率在提升 编程语言的效率是前提,js自然比不上native的C语言效率,所以Canvas效率无疑比不上原生的2D图形绘制,但是js效率的提升是有目共睹的,以js与as为例,基本操作(运算操作 ...

  9. c++语法拾遗,一些细节与特性

    写了2年多的C+STL的acmer,在学习<C++ primer>时总结的一些少见的语法特性与细节.总体还是和题目说的一样这是一篇 c++ 拾遗. 1 变量和基本类型 1.1 基本类型 1 ...

  10. 三种div点击事件

    <div id="div" onclick="alert('成功')">点击</div> var oDiv = document.get ...