官方Mono使用的GC方式:SGen GC

2024-03-03 20:36
文章标签 使用 方式 gc 官方 mono sgen

本文主要是介绍官方Mono使用的GC方式:SGen GC,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Simple Generational Garbage Collection 简称 SGen GC, 是相比Boehm GC(贝姆GC)更为先进的一种GC方式。官方Mono在2.8版本中增加了SGen GC,但默认的仍是Boehm GC。3.2版本之后,Mono正式将SGen GC作为默认GC方式。
SGen GC官方文档

与之前提到过的收集器类似,SGen GC也将堆内存分为初生代(Nursery)和旧生代(Old Generation)两代进行管理,并包含两个GC过程:Minor GC对初生代进行清理,Major GC对初生代和旧生代同时进行清理。

1. 内存分配策略

1.1 初生代

在SGen GC中,初生代是一块固定大小的连续内存,默认为4M,可以通过配置修改。这一点与G1不同,在G1中同一代的Region在物理上是不要求连续的。

为了支持多线程工作,新对象的内存分配依然在每个线程的TLAB中进行,当前每个TLAB均为4K,有提到可能会在不久后进行优化(不久是多久)。而在TLAB内部,内存分配是通过指针碰撞的方式进行的,也就是说,在SGen GC中,初生代内存并没有进行粒度划分也没有分块管理。

关于TLAB和指针碰撞在这篇文章里有介绍:分代GC前置概念(二):TLAB。

初生代对象跟随Minor GC和Major GC进行回收。

1.2 旧生代

在Mono的早期版本中使用的是贝姆GC(贝姆GC的介绍可以看这里),对于旧生代,SGen GC采取了与贝姆GC类似的管理策略。

在SGen GC中,旧生代内存划分方式可以概括为:

						Section(1M) →  Block(16K)→ Page(4K)→ Slot(不同粒度)

在使用内存时,按照上述链条依次向下拆分,与贝姆GC相同,同一个Block中的Page也只能拆分成相同粒度的Slot(文档中倒是没提到旧生代内存是否也分成三种内存类型来管理)。

虽然在初生代中并没有划分内存粒度,但是当对象从初生代转移到旧生代时会找到对应粒度的Slot进行存储。释放对象时,对应的Slot也会返还给空闲链表(类似贝姆GC中的ok_freeList),并在某一级结构完全清空时依次向上一级返还。

旧生代内存最终是通过一个GCMemSection结构的链表进行管理的。

旧生代对象跟随Major GC进行回收。

1.3 大对象

超过8K的对象均被视为大对象,大对象通过单独的LOSSection结构进行管理。而大对象的内存管理又分为两种情况:

  • 不超过1M的,仍然存储在Mono自己的托管堆上,清理后返还给托管堆
  • 超过1M的,直接从操作系统申请内存,清理后内存也同样返还给操作系统

大对象跟随Major GC进行回收。

1.4 固定内存对象

有一些对象被显式或隐式地标记为了固定内存的对象,这些对象在初始时依然被分配在初生代中,但不会被GC过程移动位置。

  • 显式:用户显式声明的,比如通过fixed关键字进行修饰
  • 隐式:在GC开始时,所有寄存器和ROOT中直接指向的对象都视为固定内存对象

固定内存对象跟随Major GC进行回收。

2. GC过程

2.1 Minor GC

只针对初生代对象进行清理,采用的是标记复制法。
触发时机为初生代内存不足时。
此过程为STW的。

Minor GC的过程平平无奇,这里只提一点。由于固定内存对象不会被移动位置,因此即使采用了标记复制的方式,初生代依然会被这些固定内存对象切割,所以在清理阶段需要对内存进行评估,来确定到底有哪些部分是真的可以用来重新分配的。上文提到当前版本TLAB的大小为4K,其实实际可用的部分往往是不足4K的。

2.2 Major GC

针对所有对象进行清理,采用标记清除法。
触发时机为旧生代内存不足时。

其核心过程基本可以概括为以下几个阶段:

  • 初始标记(STW)
  • 并发标记
  • 重标记(STW)
  • 并发清理

虽然SGen GC对于旧生代内存的分配策略与贝姆GC类似,但可以看到,其Major GC的过程却更像CMS。不了解CMS的可以看这篇:大概了解一下CMS收集器

另外,在贝姆GC中,收集器完全没有移动对象的权限,但SGen GC却不同。在清理阶段,收集器会统计各种粒度的分块的实际占用率。如果某种粒度的占用率低于指定值(这个值也是可以配置的),那么该粒度就会被标记为稀疏,在下一次Major GC时,收集器会将稀疏粒度的分块进行合并,将其中的对象复制到一个新的空内存块中依次排列(复制压缩),并将清理出来的稀疏块清空返还。

最后,由于初生代、旧生代、大对象、固定内存对象都会在Major GC中进行清理,从对象类型的角度看一下Major GC的处理过程为:

  • 识别固定对象
  • 分配一个新的Section
  • 扫描固定内存对象
  • 扫描Root
  • 移动对象(初生代晋升、合并稀疏块)
  • 清理大对象
  • 清理固定内存对象
  • 回收空Section
  • 重构初生代空间

这篇关于官方Mono使用的GC方式:SGen GC的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/770833

相关文章

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

使用Python删除Excel中的行列和单元格示例详解

《使用Python删除Excel中的行列和单元格示例详解》在处理Excel数据时,删除不需要的行、列或单元格是一项常见且必要的操作,本文将使用Python脚本实现对Excel表格的高效自动化处理,感兴... 目录开发环境准备使用 python 删除 Excphpel 表格中的行删除特定行删除空白行删除含指定

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

prometheus如何使用pushgateway监控网路丢包

《prometheus如何使用pushgateway监控网路丢包》:本文主要介绍prometheus如何使用pushgateway监控网路丢包问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录监控网路丢包脚本数据图表总结监控网路丢包脚本[root@gtcq-gt-monitor-prome

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr