简介

终于来到了GC的最后一个步骤,在此之间,大量预备工作已经完成。万事俱备,只欠东风

清除

如果GC决定不压缩,它将仅执行清除操作。清除操作非常简单,把所有不可到达对象(gap),转换成Free。也就是转换成空闲内存空间。

由于所有的繁重计算任务在plan_phase阶段均已完成,所以步骤比较简单

  1. 基于gap的size创建空闲列表

    free > 2 * min_obj_size 的Free块会被放入空闲列表,小于此大小的不再被利用,但会纳入内存碎片统计

  2. 恢复“被销毁”的前置plug和plug

    这是pinned 对象的特殊情况,pinned的plug前面可能还是一个plug,所以没有gap来存放, 因此会根据实际情况“钉住”它的前面或者后面的Plug.来暂存gap_reloc_pair信息。 所以用完后还要“还回去”

  3. 更新终结队列,并提升或降低plug的代

  4. 更新段空间

眼见为实

压缩

如果GC决定压缩,就比较复杂了。总体分为两步

  1. 复制对象并移动到新位置(重定位阶段)
  2. 将新对象的地址在root上更新

GC重定位阶段

此步骤更新所有对稍后要移动对象的引用,为了更新这些地址,要扫描他们的root,并逐一更新

  1. 栈空间的root
  2. 跨代记忆集的root
  3. 托管堆中的root
  4. 前置plug与后置Plug的root
  5. 终结器队列的root
  6. 句柄表的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要移动所有对象。由以下几个步骤组成

  1. 复制对象
  2. 恢复“被销毁”的前置plug和plug
  3. 重新划分代边界
  4. 释放内存段
  5. 创建空闲列表

眼见为实

GC前:

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

眼见为实:复制连续的内存区域

以滑动的方式来copy内存,避免出现覆盖问题

.NET Core GC压缩(compact_phase)底层原理浅谈的更多相关文章

  1. Java线上问题排查神器Arthas快速上手与原理浅谈

    前言 当你兴冲冲地开始运行自己的Java项目时,你是否遇到过如下问题: 程序在稳定运行了,可是实现的功能点了没反应. 为了修复Bug而上线的新版本,上线后发现Bug依然在,却想不通哪里有问题? 想到可 ...

  2. CSRF漏洞原理浅谈

    CSRF漏洞原理浅谈 By : Mirror王宇阳 E-mail : mirrorwangyuyang@gmail.com 笔者并未深挖过CSRF,内容居多是参考<Web安全深度剖析>.& ...

  3. JAVA CAS原理浅谈

    java.util.concurrent包完全建立在CAS之上的,没有CAS就不会有此包.可见CAS的重要性. CAS CAS:Compare and Swap, 翻译成比较并交换. java.uti ...

  4. 如何把Java代码玩出花?JVM Sandbox入门教程与原理浅谈

    在日常业务代码开发中,我们经常接触到AOP,比如熟知的Spring AOP.我们用它来做业务切面,比如登录校验,日志记录,性能监控,全局过滤器等.但Spring AOP有一个局限性,并不是所有的类都托 ...

  5. CAS+SSO原理浅谈

    http://www.cnblogs.com/yonsin/archive/2009/08/29/1556423.htmlSSO 是一个非常大的主题,我对这个主题有着深深的感受,自从广州 UserGr ...

  6. php模板原理PHP模板引擎smarty模板原理浅谈

    mvc是开发中的一个伟大的思想,使得开发代码有了更加清晰的层次,让代码分为了三层各施其职.无论是对代码的编写以及后期的阅读和维护,都提供了很大的便利. 我们在php开发中,视图层view是不允许有ph ...

  7. PHP的模板引擎smarty原理浅谈

    mvc是开发中的一个伟大的思想,使得开发代码有了更加清晰的层次,让代码分为了三层各施其职.无论是对代码的编写以及后期的阅读和维护,都提供了很大的便利. 我们在php开发中,视图层view是不允许有ph ...

  8. Docker 基础底层架构浅谈

    docker学习过程中,免不了需要学习下docker的底层技术,今天我们来记录下docker的底层架构吧! 从上图我们可以看到,docker依赖于linux内核的三个基本技术:namespaces.C ...

  9. Java中的SPI原理浅谈

    在面向对象的程序设计中,模块之间交互采用接口编程,通常情况下调用方不需要知道被调用方的内部实现细节,因为一旦涉及到了具体实现,如果需要换一种实现就需要修改代码,这违反了程序设计的"开闭原则& ...

  10. JDK source 之 LinkedHashMap原理浅谈

    注:本文参考JDK1.7.0_45源码. LinkedHashMap是基于HashMap实现的数据结构,与HashMap主要的不同为每个Entry是使用双向链表实现的,并且提供了根据访问顺序进行排序的 ...

随机推荐

  1. macos安装Charles

    一.安装jdk 1.地址:https://www.oracle.com/cn/java/technologies/downloads/#java11,下载后双击安装 2.查看java的安装地址,在ma ...

  2. golang WEB框架Hertz --- 获取参数

    安装Hertz命令行工具 请确保您的Go版本在1.15及以上版本,笔者用的版本是1.18 配置好GO的环境后,按照Hertz的命名行工具 go install github.com/cloudwego ...

  3. TreeMap源码分析——基础分析(基于JDK1.6)

    常见的数据结构有数组.链表,还有一种结构也很常见,那就是树.前面介绍的集合类有基于数组的ArrayList,有基于链表的LinkedList,还有链表和数组结合的HashMap,今天介绍基于树的Tre ...

  4. highcharts中的折线图

    折现图表的样式如下所示: 整体的一个设置代码如下: that.options = { title: { text: null }, subtitle: { text: null }, yAxis: { ...

  5. php-fpm相关操作

    php-fpm常用操作 一. php5.3.3之后使用新号方式控制php-fpm进程 INT, TERM 立即终止 QUIT 平滑终止 USR1 重新打开日志文件 USR2 平滑重启所有worker进 ...

  6. vite 分包打包

    1.概述 在使用vite打包的时候,一般情况会将依赖包和源码打包到一起,这样的问题是,一般情况依赖包一般情况是不变的,如果打包到一起,程序更新时,就会因为打包指纹发生变化而重新下载,如果进行分包,如果 ...

  7. Dapr-6 Dapr 服务调用构建块

    第 6 章 Dapr 服务调用构建块 https://docs.microsoft.com/en-us/dotnet/architecture/dapr-for-net-developers/serv ...

  8. GraphQL Part VI: 使用 Postgres 和 EF Core 持久化数据

    这次我们关注持久化数据而不是 GraphQL 方面.我们将使用 Postgres 数据库作为后端存储,您可能问:为什么要使用 Postgres?因为大家都熟悉 SQL Server,我们尝试一下新东西 ...

  9. 中电金信:产教联合共育人才 AFAC2024金融智能创新大赛启动

    当前,人工智能技术正在蓬勃发展,引领着各行各业迈向智能化的新纪元,特别是在金融科技领域,伴随人工智能技术的不断迭代与突破,金融服务的边界也在不断拓展,传统的金融业态正经历着深刻的变革与重塑. 与此同时 ...

  10. 实用干货分享(3)- Git常用操作干货分享

    官方学习地址 https://git-scm.com/book/zh/v2 简单的代码提交流程 1. git status 查看工作区代码相对于暂存区的差别: 2. git add . 将当前目录下修 ...