C++随笔:.NET CoreCLR之GC探索(3)
有几天没写GC相关的文章了哈,今天我讲GC的方式是通过一个小的Sample来讲解,这个小的示例代码只有全部Build成功了才会有。地址为D:\coreclr2\coreclr\bin\obj\Windows_NT.x64.Debug\src\gc\sample,前缀路径大家替换成自己的路径就OK了。
首先我们还是从main函数来入手吧。首先是初始化GC。
1 2 3 4 5 6 7 8 9 10 11 | int __cdecl main( int argc, char * argv[]) { // // Initialize system info // //初始化GC,如果初始化失败,则直接退出 if (!GCToOSInterface::Initialize()) { return -1; } |
下面我们来看看GCToOSInterface这个类,我只是把部分的方法罗列出来了,大家可以把这个理解为“接口”,这些方法,也应用到了设计模式,比如下面的方法的命名,是不是和EF很像呢?毕竟都是微软的东西,大家可以理解为,都是一家亲。另外,虚拟内存的分配 没有我们想的那么简单,它也是事物,对于一个事物,它的方法是丰富的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | // Interface that the GC uses to invoke OS specific functionality //GC和操作系统衔接的桥梁,你可以理解为调用特定的操作系统的特定“方法”的方法 class GCToOSInterface { public : // // Initialization and shutdown of the interface // 初始化和 关闭GC对于OS(操作系统)的接口 // Initialize the interface implementation // Return: // true if it has succeeded, false if it has failed static bool Initialize(); // Shutdown the interface implementation //终止这个方法;简单一点理解,就是.NET中的dispose()方法. static void Shutdown(); // // Virtual memory management // //虚拟内存管理 // Reserve virtual memory range. //虚拟内存存储范围 // Parameters: // address - starting virtual address, it can be NULL to let the function choose the starting address // size - size of the virtual memory range // alignment - requested memory alignment // flags - flags to control special settings like write watching // Return: // Starting virtual address of the reserved range //参数: //address(地址) - 初始的虚拟地址,如果为NULL,会让方法来选择初始的地址; //size(大小) - 虚拟内存范围的定义域; //alignment(队列) - 请求的存储队列 // flags(标识符) - 标识控制(比如是写,还是观察,或者是读); //返回:已经存储的虚拟内存的首地址; static void * VirtualReserve( void *address, size_t size, size_t alignment, uint32_t flags); // Release virtual memory range previously reserved using VirtualReserve //释放定义域内的虚拟内存,注意此定义域是“之前”分配的虚拟内存的定义域; // Parameters: // address - starting virtual address // size - size of the virtual memory range // Return: // true if it has succeeded, false if it has failed //返回 - 成功:TRUE,否则:FAIL static bool VirtualRelease( void *address, size_t size); // Commit virtual memory range. It must be part of a range reserved using VirtualReserve. //提交虚拟内存的定义域;注意提交的定义域必须是包含在“VirtualReserve分配过的”内存块。 //注意这里的commit可以理解为.NET和SQL中的“事务”; // Parameters: // address - starting virtual address // size - size of the virtual memory range // Return: // true if it has succeeded, false if it has failed static bool VirtualCommit( void *address, size_t size); // Decomit virtual memory range. //撤销提交 - 和VirtualCommit功能刚好相反; // Parameters: // address - starting virtual address // size - size of the virtual memory range // Return: // true if it has succeeded, false if it has failed static bool VirtualDecommit( void *address, size_t size); } |
下面我们来看一下Initalize这个方法,先 查询性能频率是什么意思呢?
1 2 3 4 5 6 7 8 9 | bool GCToOSInterface::Initialize() { //查询性能频率 if (!::QueryPerformanceFrequency(&performanceFrequency)) { return false ; } } |
我注意到performanceFrequency这个常量;来看看它的定义:
1 | static LARGE_INTEGER performanceFrequency; |
再看LARGE_INTEGER,发现是一个联合体,我这里 科普一下联合体,就不麻烦大家去其他地方找资料了。
-------------------------------------------------------------分割线开始------------------------------------------------------------------------
- 1、union中可以定义多个成员,union的大小由最大的成员的大小决定。
- 2、union成员共享同一块大小的内存,一次只能使用其中的一个成员。
- 3、对某一个成员赋值,会覆盖其他成员的值(也不奇怪,因为他们共享一块内存。但前提是成员所占字节数相同,当成员所占字节数不同时只会覆盖相应字节上的值,比如对char成员赋值就不会把整个int成员覆盖掉,因为char只占一个字节,而int占四个字节)
- 4、联合体union的存放顺序是所有成员都从低地址开始存放的。
-------------------------------------------------------------分割线结束------------------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //如果定义了MIDL_PASS,虽然我并不知道这是什么 #if defined(MIDL_PASS) typedef struct _LARGE_INTEGER { #else // MIDL_PASS typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; } DUMMYSTRUCTNAME; struct { DWORD LowPart; LONG HighPart; } u; #endif //MIDL_PASS LONGLONG QuadPart; } LARGE_INTEGER; |
上面的大家需要理解一些C++的基础知识,具体的大家自己去百度,下面我们再来看看QueryPerformanceFrequency这个方法,这个方法是位于WDK里面的,具体的详细介绍看这里
- typedef unsigned long DWORD;
- typedef long LONG;
- typedef __int64 LONGLONG;
1 2 3 4 | WINAPI QueryPerformanceFrequency( _Out_ LARGE_INTEGER * lpFrequency ); |
下面来看一下完整的方法,想深入研究的,可以自行研究~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | bool GCToOSInterface::Initialize() { //查询性能频率 if (!::QueryPerformanceFrequency(&performanceFrequency)) { return false ; } //系统信息 SYSTEM_INFO systemInfo; //此方法位于WDK8.1里面 GetSystemInfo(&systemInfo); //GCSystemInfo,通过WDK得到系统的信息,然后把信息赋给GCSystemInfo g_SystemInfo.dwNumberOfProcessors = systemInfo.dwNumberOfProcessors; g_SystemInfo.dwPageSize = systemInfo.dwPageSize; g_SystemInfo.dwAllocationGranularity = systemInfo.dwAllocationGranularity; return true ; } |
__EOF__
作 者:ღKawaii
出 处:https://www.cnblogs.com/kmsfan/p/5540623.html
关于博主:一个普通的小码农,为了梦想奋斗
版权声明:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本。
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!

出处:http://www.cnblogs.com/kmsfan
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
欢迎大家加入KMSFan之家,以及访问我的优酷空间!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?