有几天没写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_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;  
WINAPI
QueryPerformanceFrequency(
_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;
}

  

C++随笔:.NET CoreCLR之GC探索(3)的更多相关文章

  1. C++随笔:.NET CoreCLR之GC探索(4)

    今天继续来 带大家讲解CoreCLR之GC,首先我们继续看这个GCSample,这篇文章是上一篇文章的继续,如果有不清楚的,还请翻到我写的上一篇随笔.下面我们继续: // Initialize fre ...

  2. C++随笔:.NET CoreCLR之GC探索(2)

    首先谢谢 @dudu 和 @张善友 这2位大神能订阅我,本来在写这个系列以前,我一直对写一些核心而且底层的知识持怀疑态度,我为什么持怀疑态度呢?因为一般写高层语言的人99%都不会碰底层,其实说句实话, ...

  3. C++随笔:.NET CoreCLR之GC探索(1)

    一直是.NET程序员,但是.NET的核心其实还是C++,所以我准备花 一点时间来研究CoreCLR和CoreFX.希望这个系列的文章能给大家带来 帮助. GC的代码有很多很多,而且结构层次对于一个初学 ...

  4. CoreCLR源码探索(五) GC内存收集器的内部实现 调试篇

    在上一篇中我分析了CoreCLR中GC的内部处理, 在这一篇我将使用LLDB实际跟踪CoreCLR中GC,关于如何使用LLDB调试CoreCLR的介绍可以看: 微软官方的文档,地址 我在第3篇中的介绍 ...

  5. CoreCLR文档翻译 - GC的设计

    此文档来源于CoreCLR的BOTR(The Book of the Runtime), 点击打开原文 一切著作权归微软公司所有 GC的设计 作者: Maoni Stephens (@maoni0) ...

  6. CoreCLR源码探索(三) GC内存分配器的内部实现

    在前一篇中我讲解了new是怎么工作的, 但是却一笔跳过了内存分配相关的部分. 在这一篇中我将详细讲解GC内存分配器的内部实现. 在看这一篇之前请必须先看完微软BOTR文档中的"Garbage ...

  7. CoreCLR源码探索(四) GC内存收集器的内部实现 分析篇

    在这篇中我将讲述GC Collector内部的实现, 这是CoreCLR中除了JIT以外最复杂部分,下面一些概念目前尚未有公开的文档和书籍讲到. 为了分析这部分我花了一个多月的时间,期间也多次向Cor ...

  8. CoreCLR源码探索(一) Object是什么

    .Net程序员们每天都在和Object在打交道 如果你问一个.Net程序员什么是Object,他可能会信誓旦旦的告诉你"Object还不简单吗,就是所有类型的基类" 这个答案是对的 ...

  9. CoreCLR源码探索(二) new是什么

    前一篇我们看到了CoreCLR中对Object的定义,这一篇我们将会看CoreCLR中对new的定义和处理 new对于.Net程序员们来说同样是耳熟能详的关键词,我们每天都会用到new,然而new究竟 ...

随机推荐

  1. 如何用百度MIP快速搭建体验友好的移动页面

    在读这篇文章之前,请确定你已经了解MIP定义及加速原理.如果不确定的话,可以到MIP官网了解. 改造前期准备和注意事项: 你可以选择直接将原先的移动站点直接改成MIP站,也可以单独再做一套MIP站点与 ...

  2. Apache Ignite高性能分布式网格框架-初探

    Apache Ignite初步认识 今年4月开始倒腾openfire,过程中经历了许多,更学到了许多.特别是在集群方面有了很多的认识,真正开始认识到集群的概念及应用方法. 在openfire中使用的集 ...

  3. Spark RDD 核心总结

    摘要: 1.RDD的五大属性 1.1 partitions(分区) 1.2 partitioner(分区方法) 1.3 dependencies(依赖关系) 1.4 compute(获取分区迭代列表) ...

  4. HTML DOM 介绍

    本篇主要介绍DOM内容.DOM 节点.节点属性以及获取HTML元素的方法. 目录 1. 介绍 DOM:介绍DOM,以及对DOM分类和功能的说明. 2. DOM 节点:介绍DOM节点分类和节点层次. 3 ...

  5. WPF做12306验证码点击效果

    一.效果 和12306是一样的,运行一张图上点击多个位置,横线以上和左边框还有有边框位置不允许点击,点击按钮输出坐标集合,也就是12306登陆的时候,需要向后台传递的参数. 二.实现思路 1.获取验证 ...

  6. 关于 devbridge-autocomplete 插件多选操作的实现方法

    目前据我所知最好用的 autocomplete 插件就是 jquery-ui 的 autocomplete 以及 devbridge 的 autocomplete 插件. 我最终选择了 devbrid ...

  7. C#异步编程(二)

    async和await结构 序 前篇博客异步编程系列(一) 已经介绍了何谓异步编程,这篇主要介绍怎么实现异步编程,主要通过C#5.0引入的async/await来实现. BeginInvoke和End ...

  8. 由js apply与call方法想到的js数据类型(原始类型和引用类型)

    原文地址:由js apply与call方法想到的js数据类型(原始类型和引用类型) js的call方法与apply方法的区别在于第二个参数的不同,他们都有2个参数,第一个为对象(即需要用对象a继承b, ...

  9. .NET中AOP方便之神SheepAspect

    SheepAspect 简介以及代码示列: SheepAspect是一个AOP框架为.NET平台,深受AspectJ.它静织目标组件作为一个编译后的任务(编译时把AOP代码植入). 多有特性时,可根据 ...

  10. asp.net core 负载均衡集群搭建(centos7+nginx+supervisor+kestrel)

    概述 本文目的是搭建三台asp.net core 集群, 并配上 nginx做负载均衡   首先准备要运行的源码 http://pan.baidu.com/s/1c20x0bA 准备三台服务器(或则虚 ...