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.運行此段代碼,顯示如下
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),瞭解更多。