博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++随笔:.NET CoreCLR之GC探索(3)
阅读量:6947 次
发布时间:2019-06-27

本文共 4776 字,大约阅读时间需要 15 分钟。

  有几天没写GC相关的文章了哈,今天我讲GC的方式是通过一个小的Sample来讲解,这个小的示例代码只有全部Build成功了才会有。地址为D:\coreclr2\coreclr\bin\obj\Windows_NT.x64.Debug\src\gc\sample,前缀路径大家替换成自己的路径就OK了。

  首先我们还是从main函数来入手吧。首先是初始化GC。

int __cdecl main(int argc, char* argv[]){    //    // Initialize system info    //	//初始化GC,如果初始化失败,则直接退出    if (!GCToOSInterface::Initialize())    {         return -1;    }

  下面我们来看看GCToOSInterface这个类,我只是把部分的方法罗列出来了,大家可以把这个理解为“接口”,这些方法,也应用到了设计模式,比如下面的方法的命名,是不是和EF很像呢?毕竟都是微软的东西,大家可以理解为,都是一家亲。另外,虚拟内存的分配 没有我们想的那么简单,它也是事物,对于一个事物,它的方法是丰富的。

// 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这个方法,先 查询性能频率是什么意思呢?

bool GCToOSInterface::Initialize(){	//查询性能频率    if (!::QueryPerformanceFrequency(&performanceFrequency))    {        return false;    }}

  我注意到performanceFrequency这个常量;来看看它的定义:

static LARGE_INTEGER performanceFrequency;

  再看LARGE_INTEGER,发现是一个联合体,我这里 科普一下联合体,就不麻烦大家去其他地方找资料了。

-------------------------------------------------------------分割线开始------------------------------------------------------------------------

  1. 1、union中可以定义多个成员,union的大小由最大的成员的大小决定。 
  2. 2、union成员共享同一块大小的内存,一次只能使用其中的一个成员。 
  3. 3、对某一个成员赋值,会覆盖其他成员的值(也不奇怪,因为他们共享一块内存。但前提是成员所占字节数相同,当成员所占字节数不同时只会覆盖相应字节上的值,比如对char成员赋值就不会把整个int成员覆盖掉,因为char只占一个字节,而int占四个字节)
  4. 4、联合体union的存放顺序是所有成员都从低地址开始存放的。

-------------------------------------------------------------分割线结束------------------------------------------------------------------------

//如果定义了MIDL_PASS,虽然我并不知道这是什么#if defined(MIDL_PASS)typedef struct _LARGE_INTEGER {#else // MIDL_PASStypedef 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;  
WINAPIQueryPerformanceFrequency(    _Out_ LARGE_INTEGER * lpFrequency    );

  下面来看一下完整的方法,想深入研究的,可以自行研究~

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;}

  

 

转载于:https://www.cnblogs.com/kmsfan/p/5540623.html

你可能感兴趣的文章
WIN8系统安装软件时提示"扩展属性不一致"的解决方法
查看>>
sqlite3.exe 使用
查看>>
CAD中批量打印
查看>>
蛋疼的Apple IOS Push通知协议
查看>>
MyEclipse10.0 安装 jbpm4.4
查看>>
批处理复制文件(文件夹)排除某目录,某些类型(草稿)
查看>>
【转】shell 编程:冒号 后面跟 等号,加号,减号,问号的意义
查看>>
C#编写COM组件
查看>>
[OpenSource]浅谈.Net和Java互相调用的三种方式
查看>>
C语言指针的初始化和赋值
查看>>
安卓开发笔记——关于照片墙的实现(完美缓存策略LruCache+DiskLruCache)
查看>>
定义和使用EL函数
查看>>
android edittext不弹出软键盘
查看>>
关于正则表达式 C#
查看>>
【原创视频教程】SqlServer2008视频教程[共9集]
查看>>
Ubuntu 14.04 启用休眠
查看>>
Android闹钟源代码
查看>>
const使用摘要
查看>>
1.cocos2dx 3.2环境结构
查看>>
你知道什么是Grunt么?
查看>>