.NET GC工作流程

news/2024/9/8 5:16:07/

前言

在上文[如何获取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	//恢复托管线程运行完成

图例

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

db29776db7b7a046f1df05fc4bb93e13.png

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

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

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

e9a3edf1d60edf2fcef143c188c162ac.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(非后台)模式的执行流程。
c2324f8c91441ebd5934d2cf32c825c0.png

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

WorkstationGC模式-后台GC

下图是WorkstationGC(后台)模式的执行流程,可以看到后台模式还是相当复杂的,会短暂的暂停多次,每一次都会执行不同的操作。
5cb867140e2cdc89b98869a08d026afd.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(后台)模式的执行流程。
d2ef84e019b803cd707c36dfabc4274a.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.ppmy.cn/news/660409.html

相关文章

python遍历文件目录_Python递归遍历目录下所有文件

#自定义函数: import os path"D:\\Temp_del\\a" def gci (path): """this is a statement""" parents os.listdir(path) for parent in parents: child os.path.join(path,parent) #print(child) if os.path.is…

GBase 8s 产品架构介绍

产品架构 GBase 8s 产品构架如图 如图所示,架构图中蓝色部分均为安全数据库产品在通用数据库产品基础之上的安全增强部分。 产品组件模块 服务器组件介绍: 卷: 即 Volume, 是存储数据库数据的数据文件, GBase 8…

python实现文件的遍历

#!/usr/bin/python -- coding: utf-8 -- import os def gci(filepath): #遍历filepath下所有文件,包括子目录 files os.listdir(filepath) for fi in files: fi_d os.path.join(filepath,fi) if os.path.isdir(fi_d): gci(fi_d) else: print os.path.join(filep…

GBASE 8s 数据库开发接口

GBase 8s数据库的开发接口如下: 1.ODBC GBase 8s ODBC是GBase 8s的ODBC驱动程序,它提供了访问 GBase 8s的所有ODBC功能。GBase ODBC支持ODBC 3.5X一级规范(全部API 2级特性)。用户可以通过ODBC数据源管理器调用GBase ODBC驱动访…

记录指纹的相关博客

Repo介绍 Fingerprint指纹识别学习 Android Fingerprint – HAL层的初始化工作 Android Fingerprint – Enroll流程 Android 8.0指纹流程 Android O指纹识别解析 Android8.0 Fingerprint指纹启动流程详细分析 Android Keyguard–指纹解锁流程 《Android中级工程师》Service启动…

ELK增量同步数据【MySql->ES】

一、前置条件 1. linux,已经搭建好的logstasheskibana【系列版本7.0X】,es 的plugs中安装ik分词器 ES版本: Logstash版本: (以上部署,都是运维同事搞的,我不会部署,同事给力&#…

如何选择一个合适的网格来进行网格收敛研究

一、几何单元的类型 目前有四种不同的三维单元类型:四面体、六面体、棱柱,以及金字塔形:可以任意组合这四种单元来对任何三维模型进行网格剖分。 二、不同几何单元适用范围 1、四面体单元 四面体单元是 COMSOL 中大部分物理场的缺省单元类型…

使用kubeadm创建集群

server2 kubeadm config print init-defaults #查看默认配置信息默认从k8s.gci.io上下载组件镜像,需要翻墙才可以,所以需要修改镜像仓库: kubeadm config images list --image-repository registry.aliyuncs.com/google_containers #列出所需…

Python CGI编程详细步骤,和说说我踩的坑!!

最近在学python,刚接触python高级编程-gci编程,照着网上的资料去配置文件 ,但是其中遇到了很多问题,可以说一天都呆坑里,特记录下这些,总结下,也以便帮小伙伴们解决问题。 我参考的是这篇文章:…

走进GBase 8s之接口管理工具(一)开发接口(2)

ADO.NET GBase 8s ADO.NET 是一个提供.NET应用程序与GBase数据库之间方便、高效、安全交互的接口程序,使用100%纯C#编写,并继承了Microsoft ADO.NET类。开发人员可以使用任何一种.NET开发语言(C#、VB.NET、F#)通过GBase ADO.NET操…

Powershell入门语法

Powershell简介 由于cmd功能比较小,所以windows上诞生了新的shell类型。powershell有很多版本。不同版本的操作系统内置的powershell版本也不一样。可以升级。 $PSVersionTable:查看powershell版本。 PS C:\Users\JYT> $PSVersionTableName …

androi的AT指令

一、大概的一些AT指令 网络收集的AT指令 1、ATCGMI: 请求得到移动设备生产厂商的标识。2、ATCGMM: 请求得到移动设备模块的标识。3、ATCGMR: 请求得到改订的系统版本,修改级别和日期,以及其他相关内容。4、ATCGSN&…

美国GCI布线产品介绍(下)

室内大对数铜缆&#xff1a; <?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /> <?xml:namespace prefix v ns "urn:schemas-microsoft-com:vml" /> l 24AWG 线规大对数铜缆&#xff0c; 适用于语音主干应用…

如约停车(GCI)项目总结

今天开始第二版开发&#xff0c;先总结如下&#xff1a; 一、明确需求&#xff0c;这其实也就是常说的解决问题的思路之一。 Android开发人员通常都是根据由设计师设计好原型图和效果图进行开发&#xff0c;所以在开发时候我们要仔细琢磨每个界面的作用和意义&#xff0c;千万…

cat6 GCI about

安装模块cmd&#xff1a; insmod 模块路径/模块名.ko example: insmod /lib/modules/3.10.0-uc0/kernel/net/netfilter/xt_time.ko 移除模块cmd&#xff1a; insmod 模块名 example: insmod xt_time 添加串口脚本增减改权限&#xff1a; mount -o rw,remount / 中间层API…

华为全球联接指数(GCI)2019 :听到智能世界的蝴蝶风暴

2019年&#xff0c;对于大部分企业与个人来说&#xff0c;关键词是“等待”和“坚守”。全球经济下行压力中&#xff0c;人们开始不断审视自己的职业、岗位与机遇&#xff0c;同时对新技术改变经济、促进产业升级、数字化转型的期待似乎从来没有像今天一样迫切。 但是在此刻的我…

被G20、APEC、瑞典、新加坡、俄罗斯等引用的GCI报告,今年有什么新发现?

就在不久前&#xff0c;华为发布了全球联接指数&#xff08;GCI&#xff09;2018 报告&#xff0c;今年的核心关键词是人工智能。 自2014年开始投入研究到今天&#xff0c;GCI已经走过5年。回顾这五年的历程&#xff0c;GCI已成为业界公认的评估数字化转型的权威指标。截至当前…

python实现xml转gci

原由 在M3D软件生产三维模型的过程中,有时需要从CC导入模型,少不了要导入已经做好的控制点(相控点),貌似可以通过一个插件来实现,当然也可能存在一些问题,下面通过Python也可以实现转换。 输入参数 1、输入xml路径 输入xml的文件路径 xml长这样 2、输入相片宽度 根…

Re18:读论文 GCI Everything Has a Cause: Leveraging Causal Inference in Legal Text Analysis

诸神缄默不语-个人CSDN博文目录 论文名称&#xff1a;Everything Has a Cause: Leveraging Causal Inference in Legal Text Analysis 论文ArXiv下载地址&#xff1a;https://arxiv.org/abs/2104.09420 论文NAACL官方下载地址&#xff1a;https://aclanthology.org/2021.naacl…

Python与Java

Python 1、基础数据结构 答&#xff1a;列表、元组、字典、集合、字符串&#xff1b; 可变类型&#xff08;值改变&#xff0c;地址/ID不改&#xff09;&#xff1a;列表&#xff0c;字典&#xff1b;不可变类型&#xff08;值改变&#xff0c;地址/ID改变&#xff09;&#xf…