简介

终于来到了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. HarmonyOS Next 入门实战 - 创建项目、主题适配

    ​开发一个简单的demo,其中涉及一些鸿蒙应用开发的知识点,其中涉及导航框架,常用组件,列表懒加载,动画,深色模式适配,关系型数据库等内容,在实践中学习和熟悉鸿蒙应用开发. ​​ ​​ 首先下载并安装 ...

  2. ZCMU-1136

    思路 一个数学问题 要知道1为奇数,2^x次方一定为偶数. 偶数=奇数+奇数,而奇数=奇数*奇数,所以x一定要是奇数才可以. 注意 没告诉范围所以要往大的方向考虑 其中1能够被任一整数整除,所以前面加 ...

  3. Uri的解析

    //最基本的划分 [scheme:]scheme-specific-part[#fragment] //对scheme-specific-part进一步划分 [scheme:][//authority ...

  4. 在CodeBolcks+wxWidgets+wxSmith下的C++编程教程——用向导创建一个wxWidgets项目(sTetris)

    0.前言 我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程.我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识. 了解我编写教 ...

  5. 《JavaScript 模式》读书笔记(4)— 函数3

    这篇,我们来学习下自定义函数以及即时函数的内容. 四.自定义函数 函数可以动态定义,也可以分配给变量.如果创建了一个新函数,并且将其分配给保存了另外函数的同一个变量,那么就以一个新函数覆盖了旧函数.在 ...

  6. vscode+evernote印象笔记+markdown写在线笔记

    1. vscode安装evermonkey插件 2. vscode快捷键:Ctrl+Shift+P ,输入ever 按提示进行操作 Ever New: 创建新evernote笔记: 愉快地玩耍 点击下 ...

  7. PM的正交解调法

    1.PM的模拟调制过程 ​ PM信号是一种相位调制信号,其携带的信息保存在其信号的相位中,通过改变载波的相位来实现基带数据的传输. 其函数表达式如下: \[s(t) = A*cos(w_c*t + K ...

  8. 【Python】【Pandas】将符合条件行的某列数值改为负数

    萌狼蓝天情景还原: 支付宝/微信导出的账单,不管支出还是收入都是正数. 我想把支出的金额改成负数,其他不变就这样. 解决办法 这里用到的是pandas.apply e--下面的写法虽然比较麻烦,但是 ...

  9. unsupported message type: DefaultFullHttpResponse (expected: ByteBuf, FileRegion) 原因以及解决办法

    使用netty做http服务器的时候 用android链接 会出现这个错误 原因是http-aggregator顺序有问题 (ps:目前大部分国内博客都是这个排序有点坑爹): 官方文档说明:For c ...

  10. Linux 虚拟机重启找不到IP解决方案

    @ 目录 前言 简介 Linux 操作系统查看不到IP地址 问题描述: 第一步 :修改配置 第二步 :查看ip 第三步 :查看网卡 第四步 :重启网络 ‌Linux 网络服务重启失败解决办法 问题描述 ...