CoreCLR源码探索(三) GC内存分配器的内部实现

本文详细探讨了CoreCLR中GC内存分配器的内部实现,包括服务器GC和工作站GC的区别、GC相关的类与关系、堆段的物理结构以及小对象和大对象的内存分配流程。此外,还介绍了CoreCLR如何管理系统内存,并提供了动态调试GC分配内存过程的方法。通过阅读,读者将深入了解.NET Core运行时的内存管理机制。
摘要由CSDN通过智能技术生成

在前一篇中我讲解了new是怎么工作的, 但是却一笔跳过了内存分配相关的部分.
在这一篇中我将详细讲解GC内存分配器的内部实现.
在看这一篇之前请必须先看完微软BOTR文档中的"Garbage Collection Design",
原文地址是: https://github.com/dotnet/coreclr/blob/master/Documentation/botr/garbage-collection.md
译文可以看知平软件的译文或我后来的译文
请务必先看完"Garbage Collection Design", 否则以下内容你很可能会无法理解

服务器GC和工作站GC

关于服务器GC和工作站GC的区别, 网上已经有很多资料讲解这篇就不再说明了.
我们来看服务器GC和工作站GC的代码是怎么区别开来的.
默认编译CoreCLR会对同一份代码以使用服务器GC还是工作站GC的区别编译两次, 分别在SVR和WKS命名空间中:

源代码: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcsvr.cpp

#define SERVER_GC 1namespace SVR { 
#include "gcimpl.h"#include "gc.cpp"}

源代码: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcwks.cpp

#ifdef SERVER_GC#undef SERVER_GC#endifnamespace WKS { 
#include "gcimpl.h"#include "gc.cpp"}

当定义了SERVER_GC时, MULTIPLE_HEAPS和会被同时定义.
定义了MULTIPLE_HEAPS会使用多个堆(Heap), 服务器GC每个cpu核心都会对应一个堆(默认), 工作站GC则全局使用同一个堆.

源代码: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcimpl.h

#ifdef SERVER_GC#define MULTIPLE_HEAPS 1#endif // SERVER_GC

后台GC无论是服务器GC还是工作站GC都会默认支持, 但运行时不一定会启用.

源代码: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcpriv.h

#define BACKGROUND_GC //concurrent background GC (requires WRITE_WATCH)

我们从https://www.microsoft.com/net下回来的CoreCLR安装包中已经包含了服务器GC和后台GC的支持,但默认不会开启.
开启它们可以修改project.json中的·runtimeOptions·节, 例子如下:

{
        
  "runtimeOptions": {
        
    "configProperties": {
        
      "System.GC.Server": true,
      "System.GC.Concurrent": true
    }
  }}

设置后发布项目可以看到coreapp.runtimeconfig.json, 运行时会只看这个文件.
微软官方的文档: https://docs.microsoft.com/en-us/dotnet/articles/core/tools/project-json

GC相关的类和它们的关系

我先用两张图来解释服务器GC和工作站GC下GC相关的类的关系

图中一共有5个类型

  • GCHeap

    • 实现了IGCHeap接口, 公开GC层的接口给EE(运行引擎)层调用

    • 在工作站GC下只有一个实例, 不会关联gc_heap对象, 因为工作站GC下gc_heap的所有成员都会被定义为静态变量

    • 在服务器GC下有1+cpu核心数个实例(默认), 第一个实例用于当接口, 其它对应cpu核心的实例都会各关联一个gc_heap实例

  • gc_heap

    • 内部的使用的堆类型, 用于负责内存的分配和回收

    • 在工作站GC下无实例, 所有成员都会定义为静态变量

    • 在工作站GC下generation_table这个成员不会被定义, 而是使用全局变量generation_table

    • 在服务器GC下有cpu核心数个实例(默认), 各关联一个GCHeap实例

  • generation

    • 储存各个代的信息, 例如地址范围和使用的段

    • 储存在generation_table中, 一个generation_table包含了5个generation, 前面的是0 1 2 3代, 最后一个不会被初始化和使用

    • 在工作站GC下只有1个generation_table, 就是全局变量generation_table

    • 在服务器GC下generation_table是gc_heap的成员, 有多少个gc_heap就有多少个generation_table

  • heap_segment

    • 堆段, 供分配器使用的一段内存, 用链表形式保存

    • 每个gc_heap中都有一个或一个以上的segment

    • 每个gc_heap中都有一个ephemeral heap segment(用于存放最年轻对象)

    • 每个gc_heap中都有一个large heap

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值