简介

终于来到了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. 2023NOIP A层联测26 T4 abstract

    2023NOIP A层联测26 T4 abstract 乱证明求性质的光速幂优化题. 思路 对于每一个节点,到该节点的子树内的叶子节点的路径中(包括路径上的点),出现的值只有 \(k\times(\l ...

  2. Abp Vnext Vue版本(Vben Admin5.0)

    前言 之前有提供免费开源的基于vben2.8版本的abp vnext pro版本 abp vnext pro vben admin 2.8 vben2.8作者已经重构一个版本,命名为vben5,而vb ...

  3. python socket检测端口及ping检测

    python根据socket模块检测端口及vip #!/usr/bin/env python # -*- coding: utf8 -*- from .ping_helper import Pinge ...

  4. 如何编写一个高效的Java表达式求值程序

    当然,这个标题是有一点夺人眼球,但我确实这么做了(关于是否相信基准测试结果,这是另一个话题). 所以,上周我一直在找一个小型.实用的计算数学表达式的类库.偶然间我在stackoverflow上看到了一 ...

  5. tmux之常见问题

    1. 使用tmux ls的时候显示错误 failed to connect to server: Connection refused 解决: 查看进程是否存在 ps -aux|grep tmux 发 ...

  6. VLC 播放完毕后自动退出的问题

    1.打开设置 2.打开全部显示 3.取消自动退出

  7. 鸿蒙应用开发从入门到入行 - 篇1:HarmonyOS介绍——带你深入理解鸿蒙特性

    鸿蒙应用开发从入门到入行 第一天 - HarmonyOS介绍 导读:在本篇文章里,您将了解到HarmonyOS是什么,以及有哪些振奋人心的特性.并且猫林老师会在本篇文章里给出结论:鸿蒙必能蚕食安卓份额 ...

  8. Envoy 官网,中文指南,Envoy 实现 .NET 架构网关

    收集一些 Envoy 的资料 Envoy 实现 .NET 架构的网关系列 Envoy实现.NET架构的网关(一)静态配置与文件动态配置 Envoy实现.NET架构的网关(二)基于控制平面的动态配置 E ...

  9. ssh远程执行命令方法和Shell脚本实例

    写这篇博客之前,我google了一堆相关文章,大都是说修改/etc/sudoers,然后NOPASSWD:指定的cmd,但是真心不管用,没有远程虚拟终端这个方法就是浮云,ubuntu10.04 ser ...

  10. rocketMq4.2.0启动broker报错找不到或无法加载主类 Files\Java\jdk1.8.0_101\lib\dt.jar;C:\Program]

    假如弹出提示框提示'错误: 找不到或无法加载主类 xxxxxx'.打开runbroker.cmd,然后将'%CLASSPATH%'加上英文双引号.保存并重新执行start语句.做如下图处理 但是输出还 ...