.Net7自定义GC垃圾回收器

net7,自定义,gc,垃圾,回收 · 浏览次数 : 65

小编点评

**自定义GC垃圾回收器的步骤:** 1. **创建一个C++ DLL库项目**,其中包含两个头文件:`gcenv.base.h`和`gcinterface.h`。 2. **实现三个接口:** * `IGCHandleManagerIGCHandleStoreIGCHeap`:用于管理GC堆中的内存和指针。 * `IGCHeap`:用于分配和释放内存。 * `GC_VersionInfo`:用于获取GC版本信息。 3. **导出两个函数:** * `IGCHandleManager* GC_CreateInstance()`: 用于创建GC句柄。 * `void GC_DestroyInstance(IGCHandleManager* handle)`:用于释放GC句柄。 4. **修改`GC_VersionInfo`函数**,设置要显示的版本信息。 5. **编写自定义GC分配和释放函数**,将它们与`GC_CreateInstance`和`GC_DestroyInstance`函数关联。 6. **在项目属性中设置环境变量`DOTNET_GCName`**,指定自定义GC的名称。 7. **运行代码**,查看版本信息,应该显示自定义的版本号。 **示例代码:** ```cpp #include "gcenv.base.h" #include "gcinterface.h" // ... void GC_VersionInfo(VersionInfo* result) { result->MajorVersion = GC_INTERFACE_MAJOR_VERSION; result->MinorVersion = GC_INTERFACE_MINOR_VERSION; result->BuildVersion = 0; result->Name = "Custom"; } // ... // 在GC_CreateInstance函数中创建GC句柄 IGCHandleManager* GC_CreateInstance() { // 创建GC句柄 } // 在GC_DestroyInstance函数中释放GC句柄 void GC_DestroyInstance(IGCHandleManager* handle) { // 释放GC句柄 } ```

正文

1.前言

CLR和GC高度耦合,.Net7里面分离CLR和GC,则比较容易实现这件事情。本篇来看下,自定义一个GC垃圾回收器。

2.概述

这里首先演示下自定义GC垃圾回收后的效果。
1.下载Custom.dll
2.找到当前.Net目录,比如这里的7.0.10

C:\Program Files\dotnet\shared\Microsoft.NETCore.App\7.0.10

把Custom.dll复制到此目录
3.比如有以下C#代码:

 static void Main(string[] args){
     Console.WriteLine("Hello Main");
     Program pm = new Program();
     pm = null;
     GC.Collect();
 }

在项目属性-》调试-》常规-》打开调试启动配置文件UI-》环境变量里面填写如下键值:

名称:DOTNET_GCName
值:Custom.dll

4.运行此段代码,显示如下
image
hello Jianghupt这三条语句就是Custom.dll里面自定义了GC的标识效果。表示它是自定义的。
5.原理
CLR在初始化的时候,会判断是否有DOTNET_GCName环境变量,如果有则替换掉默认的GC回收器,用DOTNET_GCName指定的GC回收器。这里很明显的就是进入了自定义垃圾回收器里面去了。如果取消掉DOTNET_GCName环境变量,则不会有这三句话。可以自己去尝试下。


如何自定义GC垃圾回收呢?

自定义GC垃圾回收器,需要进行如下操作。新建一个C++ DLL库项目
引入两个头文件,实现三个接口

#include "gcenv.base.h"
#include "gcinterface.h"

IGCHandleManager
IGCHandleStore
IGCHeap

需要导出两个函数

extern "C" DLLEXPORT HRESULT
GC_Initialize(
    /* In */  IGCToCLR* clrToGC,
    /* Out */ IGCHeap** gcHeap,
    /* Out */ IGCHandleManager** gcHandleManager,
    /* Out */ GcDacVars* gcDacVars
)
{
    printf("Hello Jianghupt! This Is Custom GC Into CLR!!!!!!!!!\r\n");
    printf("Hello Jianghupt! Welcom To Customer GC CLR!!!!!!!!!\r\n");
    printf("Hello Jianghupt! Microsfot The GC Update Customer!!!!!!!!!\r\n");
    IGCHeap* heap = new CustomGCHeap(clrToGC);
    IGCHandleManager* handleManager = new CustomGCHandleManager();
    *gcHeap = heap;
    *gcHandleManager = handleManager;
    return S_OK;
}

extern "C" DLLEXPORT void
GC_VersionInfo(
    /* Out */ VersionInfo* result
)
{
	result->MajorVersion = GC_INTERFACE_MAJOR_VERSION;
	result->MinorVersion = GC_INTERFACE_MINOR_VERSION;
    result->BuildVersion = 0;
    result->Name = "Custom";
}

可以看到GC_Initialize里面的三句话,就是上面控制台显示的三句话。这个时候它实际上已经进入到了自定义GC里面去了。

源码下载

有任何问题,可以关注公众号(jianghupt),了解更多。
image

与.Net7自定义GC垃圾回收器相似的内容:

.Net7自定义GC垃圾回收器

1.前言 CLR和GC高度耦合,.Net7里面分离CLR和GC,则比较容易实现这件事情。本篇来看下,自定义一个GC垃圾回收器。 2.概述 这里首先演示下自定义GC垃圾回收后的效果。 1.下载Custom.dll 2.找到当前.Net目录,比如这里的7.0.10 C:\Program Files\do

在 Net7.0环境下测试了 Assembly.Load、Assmebly.LoadFile和Assembly.LoadFrom的区别

一、简介 很长时间没有关注一些C#技术细节了,主要在研究微服务、容器、云原生、容器编排等高大上的主题了,最近在写一些框架的时候,遇到了一些和在 Net Framework 框架下不一样的情况,当然了,我今天主要测试的是,在通过【添加项目引用】和【手动拷贝DLL】的情况下,这三个方法加载程序集:Ass

.NET性能系列文章一:.NET7的性能改进

这些方法在.NET7中变得更快 照片来自 CHUTTERSNAP 的 Unsplash 欢迎阅读.NET性能系列的第一章。这一系列的特点是对.NET世界中许多不同的主题进行研究、比较性能。正如标题所说的那样,本章节在于.NET7中的性能改进。你将看到哪种方法是实现特定功能最快的方法,以及大量的技巧和

试试将.NET7编译为WASM并在Docker上运行

之前有听到说Docker支持Wasmtime了,刚好.NET7也支持WASM,就带大家来了解一下这个东西,顺便试试它怎么样。 因为WASM(WebAssembly) 一开始是一个给浏览器的技术,比起JS解释执行,WASM能用于提升浏览器的用户体验,因为在一些场景中它有着比JS更好的性能。 大家可以将

使用.NET7和C#11打造最快的序列化程序-以MemoryPack为例

## 译者注 本文是一篇不可多得的好文,MemoryPack 的作者 neuecc 大佬通过本文解释了他是如何将序列化程序性能提升到极致的;其中从很多方面(可变长度、字符串、集合等)解释了一些性能优化的技巧,值得每一个开发人员学习,特别是框架的开发人员的学习,一定能让大家获益匪浅。 ## 简介 我发

在 Net7.0 环境下使用 RestSharp 发送 Http(FromBody和FromForm)请求

一、简介 最近,在做一个数据传输的服务,我在一个Worker Service里面需要访问 WebAPI 接口,并传输数据,也可以提交数据。由于第一次使用 RestSharp 发送请求,也遇到了很多问题,不过最终把问题都解决了。什么东西都一样,第一次做都会才很多坑。 今天,我就两个小的知识点,就是通过

在 Net7.0环境下通过反射创建对象和调用方法

一、介绍 最近没事干,就用闲暇时间写点东西,也记录一下温习历程。老人说的好,好记性,不如烂笔头。时间一长,当时记忆的再清楚,都会变得模糊,索性就写博客记录下来,如果下次需要,直接打开博客就找到了,不用去网上乱找了。 今天我要写一些有关反射创建类型实例和调用方法的文章,泛型的类型的创建和泛型方法的调用

Debian12安装.NET7 SDK

Debian,作为最受欢迎的 Linux 发行版之一,于 2023 年 6 月 10 日正式发布了其最新版本 Debian 12,代号“Bookworm”。Debian 12 带来了许多新特性和改进,其中最引人注目的是 Linux 内核的升级,从之前的 5.10 LTS 升级到了 6.1。 这两天尝

从 WinDbg 角度理解 .NET7 的AOT玩法

一:背景 1.讲故事 前几天 B 站上有位朋友让我从高级调试的角度来解读下 .NET7 新出来的 AOT,毕竟这东西是新的,所以这一篇我就简单摸索一下。 二:AOT 的几个问题 1. 如何在 .NET7 中开启 AOT 功能 在 .NET7 中开启 AOT 非常方便,先来段测试代码。 interna

【Azure 存储服务】.NET7.0 示例代码之上传大文件到Azure Storage Blob (一)

问题描述 在使用Azure的存储服务时候,如果上传的文件大于了100MB, 1GB的情况下,如何上传呢? 问题解答 使用Azure存储服务时,如果要上传文件到Azure Blob,有很多种工具可以实现。如:Azure 门户, Azure Storage Explorer, 命令行工具 az copy