.Net7自定義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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章