.NET Core GC压缩(compact_phase)底层原理浅谈
简介
终于来到了GC的最后一个步骤,在此之间,大量预备工作已经完成。万事俱备,只欠东风
清除
如果GC决定不压缩,它将仅执行清除操作。清除操作非常简单,把所有不可到达对象(gap),转换成Free。也就是转换成空闲内存空间。
由于所有的繁重计算任务在plan_phase阶段均已完成,所以步骤比较简单
基于gap的size创建空闲列表
free > 2 * min_obj_size 的Free块会被放入空闲列表,小于此大小的不再被利用,但会纳入内存碎片统计恢复“被销毁”的前置plug和plug
这是pinned 对象的特殊情况,pinned的plug前面可能还是一个plug,所以没有gap来存放, 因此会根据实际情况“钉住”它的前面或者后面的Plug.来暂存gap_reloc_pair信息。 所以用完后还要“还回去”更新终结队列,并提升或降低plug的代
更新段空间

眼见为实

压缩
如果GC决定压缩,就比较复杂了。总体分为两步
- 复制对象并移动到新位置(重定位阶段)
- 将新对象的地址在root上更新
GC重定位阶段
此步骤更新所有对稍后要移动对象的引用,为了更新这些地址,要扫描他们的root,并逐一更新
- 栈空间的root
- 跨代记忆集的root
- 托管堆中的root
- 前置plug与后置Plug的root
- 终结器队列的root
- 句柄表的root
比如某个对象的内存地址为0x1000,压缩后它的新地址为0x500。那就就要对该对象的所有root更新内存地址。
眼见为实
点击查看代码
internal class Program
{
static void Main(string[] args)
{
Append();
AppendStatic();
Compact();
}
public static Person person;
public static List<byte[]> list = new List<byte[]>();
static void Append()
{
//填 10M 数组到 临时段上
for (int i = 0; i < 1024 * 10; i++)
{
list.Add(new byte[1000]);
}
Console.WriteLine("1. 10M 数据已分配完毕,请查看临时段大小,准备分配 Person 对象!");
Debugger.Break();
}
static void AppendStatic()
{
person = new Person();
list = null;
Console.WriteLine("2. Person 已分配,list已去根,请再次观察托管堆!准备触发 GC,请下 compact_phase 断点!");
Debugger.Break();
}
static void Compact()
{
GC.Collect(2, GCCollectionMode.Forced, true, true);
Console.WriteLine("3. GC 已触发,请观察 Person 是否已变!");
Debugger.Break();
}
}
public class Person { }
在bp coreclr!WKS::gc_heap::compact_phase 下断点,观察对象的新老地址变化
GC前:

GC后:内存地址发生变化

眼见为实

压缩对象
在上面更新root的操作完成后,GC要移动所有对象。由以下几个步骤组成
- 复制对象
- 恢复“被销毁”的前置plug和plug
- 重新划分代边界
- 释放内存段
- 创建空闲列表
眼见为实
GC前:

GC后:对象被移动,原有地址被压缩释放

眼见为实:复制连续的内存区域
以滑动的方式来copy内存,避免出现覆盖问题

.NET Core GC压缩(compact_phase)底层原理浅谈的更多相关文章
- Java线上问题排查神器Arthas快速上手与原理浅谈
前言 当你兴冲冲地开始运行自己的Java项目时,你是否遇到过如下问题: 程序在稳定运行了,可是实现的功能点了没反应. 为了修复Bug而上线的新版本,上线后发现Bug依然在,却想不通哪里有问题? 想到可 ...
- CSRF漏洞原理浅谈
CSRF漏洞原理浅谈 By : Mirror王宇阳 E-mail : mirrorwangyuyang@gmail.com 笔者并未深挖过CSRF,内容居多是参考<Web安全深度剖析>.& ...
- JAVA CAS原理浅谈
java.util.concurrent包完全建立在CAS之上的,没有CAS就不会有此包.可见CAS的重要性. CAS CAS:Compare and Swap, 翻译成比较并交换. java.uti ...
- 如何把Java代码玩出花?JVM Sandbox入门教程与原理浅谈
在日常业务代码开发中,我们经常接触到AOP,比如熟知的Spring AOP.我们用它来做业务切面,比如登录校验,日志记录,性能监控,全局过滤器等.但Spring AOP有一个局限性,并不是所有的类都托 ...
- CAS+SSO原理浅谈
http://www.cnblogs.com/yonsin/archive/2009/08/29/1556423.htmlSSO 是一个非常大的主题,我对这个主题有着深深的感受,自从广州 UserGr ...
- php模板原理PHP模板引擎smarty模板原理浅谈
mvc是开发中的一个伟大的思想,使得开发代码有了更加清晰的层次,让代码分为了三层各施其职.无论是对代码的编写以及后期的阅读和维护,都提供了很大的便利. 我们在php开发中,视图层view是不允许有ph ...
- PHP的模板引擎smarty原理浅谈
mvc是开发中的一个伟大的思想,使得开发代码有了更加清晰的层次,让代码分为了三层各施其职.无论是对代码的编写以及后期的阅读和维护,都提供了很大的便利. 我们在php开发中,视图层view是不允许有ph ...
- Docker 基础底层架构浅谈
docker学习过程中,免不了需要学习下docker的底层技术,今天我们来记录下docker的底层架构吧! 从上图我们可以看到,docker依赖于linux内核的三个基本技术:namespaces.C ...
- Java中的SPI原理浅谈
在面向对象的程序设计中,模块之间交互采用接口编程,通常情况下调用方不需要知道被调用方的内部实现细节,因为一旦涉及到了具体实现,如果需要换一种实现就需要修改代码,这违反了程序设计的"开闭原则& ...
- JDK source 之 LinkedHashMap原理浅谈
注:本文参考JDK1.7.0_45源码. LinkedHashMap是基于HashMap实现的数据结构,与HashMap主要的不同为每个Entry是使用双向链表实现的,并且提供了根据访问顺序进行排序的 ...
随机推荐
- MySQL无开通SQL全审计下的故障分析方法
几年前MySQL数据库出现突然的从库延迟故障和CPU爆高时,如何排查具体原因,可能说已在腾讯云的MySQL库里开启了SQL全审计,记录了全部执行的SQL,再通过下面的方法就可以很容易找到原因: 1,实 ...
- IPC-7093A-CN 中文 2020底部端子元器件(BTCs)设计和组装工艺的实施
IPC-7093A 标准为实施底部端子元器件(BTCs)提供了基本的设计和组装指南.具体而言,IPC-7093A 提供了与 BTCs 相关的关键设计.材料.组装.检查.维修.质量和可靠性问题的指南. ...
- Tensorflow/Keras、Pytorch 杂记
Tensorflow/Keras 直接从文件生成图片数据 ImageDataGenerator,循环生成图片,在重复生成图片之前,会把所有图片都遍历一遍.而且如果图片总量不是生成批量的倍数的话,在生成 ...
- 解码OutOfMemoryError:PermGen Space
本文由 ImportNew - Peter Pan 翻译自 javacodegeeks.如需转载本文,请先参见文章末尾处的转载要求. ImportNew注:如果你也对Java技术翻译分享感兴趣,欢迎加 ...
- go build tags使用
转载请注明出处: 在 Go 语言中,构建标签(Build Tags)是一种用于条件编译的机制,可以帮助开发者根据不同的条件选择性地编译特定的代码块.它们在处理多平台和多环境的代码时特别有用,例如为不同 ...
- Flutter之GetX之GetBuilder
Flutter之GetX之GetBuilder GetX是Flutter的一个非常强力的三方库,包含了非常多的功能,比如状态管理.路由管理.国际化.路由中间件.主题.数据库等等 今天简单介绍一下状态管 ...
- 超实用干货(1)-Apache greenplum在aarch64架构体系的适配编译
编译环境 操作系统:EulerOS 2.0 sp8 ● 内核:4.19.36 ● CPU:aarch64 编译所需软件类别 cmake-3.23.0-rc1.tar.gz 下载地址: https:// ...
- 【SpringMVC】获取请求参数的方式
SpringMVC获取请求参数的方式 目录 SpringMVC获取请求参数的方式 方式1:ServletAPI 方法2:通过控制器方法的形参获取请求参数 方法3:@RequestParam 方法4:@ ...
- gitlab-runner register
[root@g ~]# gitlab-runner register Runtime platform arch=amd64 os=linux pid=23614 revision=ac8e767a ...
- springboot 多数据源(aop方式)
一.实现思路 在yml中定义多个数据源的配置,然后创建一个类DynamicDataSource去继承AbstractRoutingDataSource类 AbstractRoutingDataSour ...