.NET GC工作流程

前言

在上文[如何获取GC的STW时间]一文中,我们聊到了如何通过监听GC发出的诊断事件来计算STW时间。里面只简单的介绍了几种GC事件和它的流程。
群里就有小伙伴在问,那么GC事件是什么时候产生的?分别是代表什么含义?
那么在本文就通过几个图为大家解答一下这个问题。

有哪些GC模式?

工作站和服务器模式

在.NET中,GC其实有一些不同的工作模式,根据客户端和服务器可以分为如下两种模式:

Workstation GC

Workstation GC(工作站GC),这种模式主要是为了满足基于UI的交互式应用程序设计的,交互式意味着GC的暂停时间要尽可能的短。因为我们不想因为触发GC导致较长的GC停顿。

  • GC会更频繁的发生,每次暂停时间都会很短。

  • 内存占用率更低,因为GC更频繁的发生,所以内存回收的更积极,占用率也会更低。

  • 无论是否有配置多CPU核心,垃圾回收始终只使用一个CPU核心,只有一个托管堆。

  • 内存段的大小设置会很小。

Server GC

Server GC (服务器GC),这种模式主要是为了满足基于请求处理的WEB等类型应用程序设计的,这意味着它更侧重于需要满足大的吞吐量,零星的停顿不会对齐产生重大的影响。

  • GC的发生频率会降低,优先满足大吞吐量。

  • 内存占用率会更高,因为GC发生的频率变低,内存中可能会有很多垃圾对象。

  • 垃圾回收使用高优先级运行在多个专用线程上。每个CPU核心都提供执行垃圾回收的专用线程和堆,每个CPU核心上的堆都包含小对象、大对象堆。

  • 因为多个垃圾回收线程一起工作,所以对于相同大小的堆,Server GC会回收的更快一些。

  • 服务器垃圾回收通常会有更大的Segment,另外也会占用更多的资源。

并发与非并发模式

另外根据GC相对于用户线程的操作方式,还可以分为下面两种方式:

Non-Concurrent

Non-Concurrent(非并发GC),这种方式是一直存在于.NET中的,它适用于工作站和服务器模式,在GC进行过程中,所有的用户线程都会挂起

Concurrent(已过时)

Concurrent (并发GC),并发GC模式它和用户线程同时工作,GC进行过程中只有少数几个过程需要挂起用户线程。所以它的实现也更加复杂,但是暂停时间会更短,性能也会更好,不过现在它已经过时,本文不会着重描述它。

Background

Background(后台GC),在.NET Framework 4.0以后,后台GC取代了并发GC,它只适用于Gen2的回收,但是它可以触发对于Gen0、Gen1的回收。根据WorkstationGC和ServerGC的模式会分别在一个或多个线程上执行。

GC工作流程

需要知道的GC事件

其实对于我们分析GC的工作来说,上文中提到的几个事件已经足够使用了,让我们再来回顾一下这些事件。

Microsoft-Windows-DotNETRuntime/GC/SuspendEEStart	//开始暂停托管线程运行Microsoft-Windows-DotNETRuntime/GC/SuspendEEStop	//暂停托管线程完成Microsoft-Windows-DotNETRuntime/GC/Start	// GC开始回收Microsoft-Windows-DotNETRuntime/GC/Stop		// GC回收结束Microsoft-Windows-DotNETRuntime/GC/RestartEEStart	//恢复之前暂停的托管线程Microsoft-Windows-DotNETRuntime/GC/RestartEEStop	//恢复托管线程运行完成

图例

为了让大家能更清晰的看懂下面的图,会用不同形状和颜色的图像来代表不同的含义,如下方所示:

fb61f247f17318aee6d5803ea73c34e8.png

绿色:正在运行的用户线程。
红色:执行引擎进行线程冻结或线程恢复。
实线箭头:正在运行的GC线程。
虚线箭头:被暂停的线程。
黄色圆球:GC事件。
红色圆球:标记点。

WorkstationGC模式-非后台(并发)GC

下图是WorkStationGC(非后台)模式的执行流程,我们假设它是在一个双核的机器上运行(下文中都是假设在双核机器上运行),运行过程其实就像下图所示。

72330904cf45db96782eda30bf20c699.png

在上图中的事件流如下所示:

  1. GC/SuspendEEStart

  2. GC/SuspendEEStop

  3. GC/Start

  4. GC/Stop

  5. GC/RestartEEStart

  6. GC/RestartEEStop

其中各个标记点分别完成了如下工作:

  • A->B:暂停所有用户线程

  • B->C: 挑选一个用户线程作为GC线程,然后开始进行垃圾回收

    • 选择-需要被回收的一代

    • 标记-被回收的一代和更年轻一代对象

    • 计划-GC决定是需要压缩整理堆还是只是清扫堆就够了

    • 清扫、搬迁和压缩-根据上面计划的结果,执行清扫堆,或者搬迁活着的对象然后整理堆,最后所有对象的地址更新到新地址。

  • C->D: GC工作结束,恢复线程运行
    由于GC暂停了所有的线程,所以A->D就是此类GC的STW Time时间。

ServerGC模式-非后台(并发)GC

下图是ServerGC(非后台)模式的执行流程。
7d21e7ebddff17d8cdc6d5c1491afb9a.png

它与WorkstationGC模式的事件流和完成的工作都一致,唯一不同的就是它会根据当前的CPU逻辑核心数量创建单独的GC线程,比如上图就有2个GC线程。
另外在服务器GC模式中,用户线程还是可以作为GC线程来使用的,像用户线程1在GC发生的时候就做了一些GC工作。

WorkstationGC模式-后台GC

下图是WorkstationGC(后台)模式的执行流程,可以看到后台模式还是相当复杂的,会短暂的暂停多次,每一次都会执行不同的操作。
ff6df21432a3c3519380a8ee42592f9c.png
除了工作线程GC以外,另外会有单独的后台GC线程进行后台垃圾回收。
上图中的事件流如下所示:

  1. GC/SuspendEEStart

  2. GC/SuspendEEStop

  3. GC/Start

  4. GC/RestartEEStart

  5. GC/RestartEEStop

  6. GC/SuspendEEStart

  7. GC/SuspendEEStop

  8. GC/RestartEEStart

  9. GC/RestartEEStop

  10. GC/SuspendEEStart

  11. GC/SuspendEEStop

  12. GC/Start

  13. GC/Stop

  14. GC/RestartEEStart

  15. GC/RestartEEStop

  16. GC/Stop

其中各个标记点完成的工作如下所示:

  • A->B:初始选择、标记

    • 此时用户线程是暂停的

    • 选择需要被回收的一代

    • 找到GC roots,以便并发标记

  • B->C:并发标记

    • 此时用户线程是正常运行的

    • 从上一步中找到的GC roots开始标记需要被回收的一代和年轻的代

  • D->E:最终标记

    • 此时用户线程是暂停的

    • 扫描在并发标记过页面,看看是否有修改让对象重新活过来的

  • F->G:清扫小对象堆

    • 此时用户线程是正常运行的

    • 清扫小对象堆的对象

  • H->I:压缩整理小对象堆、清扫压缩整理大对象堆

    • 此时用户线程是暂停的

    • 选择了一个用户线程进行GC

    • 用来压缩小对象堆的对象

    • 另外也会压缩和整理大对象堆对象

  • J->K:清扫大对象堆

    • 此时用户线程是正常运行的

    • 此时会清扫和整理大的对象堆

    • 此时会禁止分配大对象,阻塞对应线程直到大对象堆回收完成

从上面的的流程中可以看到,后台GC主要是通过并发+多次短暂暂停来实现提升吞吐量和降低总体的STW Time的,其内部实现是非常复杂的,有兴趣的小伙伴可以直接看dotnet/runtime/gc.cpp文件。

ServerGC模式-非后台GC

下图是ServerGC(后台)模式的执行流程。
696cca275c1d665b038dc3cbaa8008f0.png
它与WorkstationGC模式的事件流和完成的工作都一致,唯一不同的就是它会根据当前的CPU逻辑核心数量创建单独的GC线程,比如上图就有2个GC线程,2个后台GC线程。

总结

今天带了解了一下.NET GC中的各个阶段和事件的顺序,当然这里只是简单的带大家了解一下,要知道在任何有runtime的平台中,GC是其中相当关键的东西,大家如果对GC感兴趣,可以阅读附录中的资料。

附录

  • https://docs.microsoft.com/zh-cn/dotnet/standard/garbage-collection/

  • https://github.com/dotnet/runtime/blob/main/src/coreclr/gc/gc.cpp

  • https://netcoreimpl.github.io/

  • http://www.tup.tsinghua.edu.cn/booksCenter/book_08454701.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/284904.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

libco协程库源码解读

2019独角兽企业重金招聘Python工程师标准>>> 协程,又被称为用户级线程,是在应用层被调度,可以减少因为调用系统调用而阻塞的线程切换的时间.目前有很多协程的实现,由于微信内部大量使用了其直研的的libco协程库,所以我选择了腾讯开源的libco协程库进行研…

【ArcGIS风暴】如何将矢量数据(点、线、面)折点坐标转为GeoJSON格式?

本文以案例的形式,讲述在ArcGIS和QGIS专业软件中,将矢量数据转为GeoJSON的方法。 扩展阅读:【GIS风暴】GeoJSON数据格式案例全解 文章目录 一、ArcGIS将矢量数据转为GeoJSON二、QGIS将矢量数据转为GeoJSON一、ArcGIS将矢量数据转为GeoJSON ArcGIS中提供的【要素转JSON】工具…

TypeScript 3.9 正式发布!平均编译时长从 26 秒缩短至 10 秒

作者 | 微软官方博客 译者 | 核子可乐 策划 | 小智 稿源 | 前端之巅 今天,微软在其官方博客宣布:TypeScript 3.9 版本已经正式发布,详情见下文。 有些朋友可能对 TypeScript 还不太熟悉,这是一种以 JavaScript 为基础开发的语…

(二)Harbor WEB的使用

接上一篇《安装Harbor》,安装好之后,接下来我们就进行Harbor web界面的操作吧! 转载请标明出处:http://www.cnblogs.com/huangjc/p/6270405.html 浏览器登陆Harbor(默认用户密码:admin/Harbor12345&#x…

iVX低代码平台系列制作简单的登录界面

一、前言 iVX是啥,不理解的小伙伴可以猛戳这里 ----------------------点我 二、iVX平台和现有编程语言的对比 三、iVX平台和现有编程语言的对比 1、快速学习(周期短) iVX逻辑上相对是比较简单的 所以初学者的话只需要从逻辑和具体功…

Process.Start 为什么会引发“系统找不到指定的文件”异常

前言偶然发现,如果想用如下代码在 .NET 6 中打开指定 URL:Process.Start("https://baidu.com");会引发异常:而同样的代码在 .NET Framework 中是可以正常执行的。难道,.NET 6 下的实现逻辑不一样?深入探究通…

JVM 类型的生命周期学习

Java虚拟机通过装载、连接和初始化一个JAVA类型,使该类型可以被正在运行的JAVA程序所使用,其中,装载就是把二进制形式的JAVA类型读入JAVA虚拟机中;而连接就是把这种读入虚拟机的二进制形式的类型数据合并到虚拟机的运行时状态中去…

js对象数组中的某属性值 拼接成字符串

var arr[{id: "600", pId: null, name: "图形的变化"},{id: "630", pId: "600", name: "投影与视图"},{id: "631", pId: "630", name: "投影"},{id: "632", pId: "630",…

开店星简直就是国内优秀的开源商城系统天花板

一、场景 1、大学生毕业设计做商城系统背景 好家伙、又到开学季节了,师妹让我帮忙给指导大四的项目,作为毕业设计和为后面找工作积累项目经验,要搞一个买卖二手闲置品的商城小程序和PC端商城、希望能够快速学习、接入、修改部分功能&#xff…

【CASS精品教程】CASS9.1土方量的计算方法汇总

CASS9.1中,计算土方量的方法有:DTM法土方计算、断面法进行土方量计算、方格网法土方计算、等高线法土方计算、区域土方量平衡等。本文以案例的形式,详细讲解土方量的计算过程。 文章目录 一、DTM法土方计算二、断面法进行土方量计算三、方格网法土方计算四、等高线法土方计算…

VS2019 禁止Web项目停止调试后自动关闭浏览器(在浏览器窗口关闭时停止调试程序,在调试停止时关闭浏览器)

很多文章都说要修改以下两处与“编辑并继续”有关的选项: “编辑并继续”是一种省时的功能,使你能够在程序处于中断模式时更改源代码。 通过选择执行命令(如 "继续" 或 "单步执行")继续执行程序时&#xff0c…

【ArcGIS风暴】ArcGIS中等高线高程标注/注记(打断/消隐)方法案例汇总

本文以案例的形式,图文并茂详细讲解在ArcGIS 10.6中,等高线高程标注、注记的方法。 文章目录 一、属性标注二、Maplex工具标注1. 使用Maplex标注引擎2. 标注转换为注记3. 要素轮廓线掩膜4. 使用掩膜选项进行绘制参考阅读: 【CASS精品教程】CASS9.1等高线的绘制完整案例教程 …

Blazor University (35)表单 —— 编写自定义验证

原文链接:https://blazor-university.com/forms/writing-custom-validation/编写自定义验证源代码[1]请注意,与有关 EditContext、FieldIdentifiers 和 FieldState[2] 的部分一样,这是一个高级主题。如前所述,FieldState 类保存表…

HTML 元素内部添加预加载

CSS: /*元素内部加载loading*/.innerLoading {height: 100%;width: 100%;display: flex;justify-content: center;align-items: center;}.innerLoading * {text-align: center;color: #737782cc;fill: #73777A;font-size: 1em !important;font-family: SimSun,SimHe…

Windows下怎样安装Tomcat

Tomcat 是开源的WEB应用容器,所以受到各位程序员和公司的亲赖。在这里给大家介绍一下如何在Windows环境下安装Tomcat绿色版本,希望能够对大家有帮助。 1.首先去Tomcat官网下载Tomcat软件,在百度中搜索Tomcat,进入英文网址http://tomcat.apach…

智能识别云服务端平台之神【合合信息TextIn】

一、前言 众所周知,随着互联网和人工智能的发展,我们非常多的场景需要用到智能“识别”功能,比如人脸识别、通用文字识别、表格识别、办公文档识别、身份证、名片、营业执照等国内外卡证文字识别等等,同时识别与理解面临的全球性技…

【ArcGIS微课1000例】0015:ArcGIS如何创建/自定义快捷键?

为了提高工作效率,强大的ArcGIS提供了很多快捷键,如访问 ArcMap 菜单命令、窗口操纵、刷新或暂停地图绘制、通过拖放进行移动或复制等等。本文在ArcGIS已有快捷键的基础之上,为了提高工作效率,讲解如何定制个性化的快捷键。 参考阅读:【ArcGIS风暴】ArcGIS快捷键大全 文章…

Bresenham 算法

1965 年,Bresenham 为数字绘图仪开发了一种绘制直线的算法,该算法同样使用于光栅扫描显示器,被称为 Bresenham 算法。 原理 算法的目标是选择表示直线的最佳光栅位置。Bresenhan 算法在主位移方向上每次递增一个单位。另一个方向的增量为 0…

ML.NET 更新

点击上方蓝字关注我们(本文阅读时间:5分钟)ML.NET是一款面向.NET开发人员的开源,跨平台机器学习框架,可以将自定义机器学习集成到.NET应用中。我们很开心地向您介绍我们在过去几个月中所做的工作。ML.NET:https://dotnet.microsof…

Andriod之提示java.lang.SecurityException: getDataNetworkTypeForSubscriber导致程序奔溃

1、问题 修改targetSdkVersion 33 适配Android13后4G网络环境被其它app拉起来提示这个异常 2、原因 我们定位到代码在这行函数 telephonyManager.getNetworkType()Android11 的权限有关,由于缺少该权限导致无法访问接口而提示安全异常 3、解决办法 方法1:我们直接申请RE…