本文内容是学习CLR.via C#的21章后个人整理,有不足之处欢迎指导。

昨天是1024,coder的节日,我为自己coder之路定下一句准则--保持学习,保持自信,保持谦逊,保持分享,越走越远。

第一部分—基本原理思想

垃圾回收机制是针对托管堆而言。

不同于C的运行时堆,托管堆是内存是连续的,每次分配新内存,NextObjPtr指针只需要加上新分配内存块大小即可。C运行时堆为了维护链表的完整性,每当分配新的内存时,遍历链表,一旦发现足够大的内存块,则拆分块,修改节点中的指针。从托管堆中分配内存的速度,几乎可以与线程栈分配相媲美。

GC机制回收的就是托管堆中的垃圾对象。

第二部分—基本算法思想

GC检查托管堆中是否有不再使用的对象。

那么什么是不再使用的对象?

首先要解释什么是根(root)。每个应用程序都有一组根,每个根都是一个存储位置,其中包含指向引用类型对象的一个指针。该指针要么运用托管堆中的一个对象,要么为null。类型中定义的任何静态字段被认为是一个根,任何方法参数或者局部变量也被认为是一个根。只有引用类型变量,才被认为是根,值类型的变量永远不被认为是根。

GC开始执行时,假设所有对象都是垃圾。

GC沿着线程栈上检查所有的根,如果发现了一个跟引用堆中的对象,则在这个对象的“同步索引字段”上开启一位,也就是将这个bit设置为1,也就是说这个对象被标记了。

GC就是这样,以递归的方式遍历所有可达的对象。可达的对象也就是说有根的对象,就是在标记阶段被标记的,也就是本次不回收的。所以不可达的对象就被回收了。

进入第二阶段--压缩阶段。

实际上此压缩非彼压缩,在这里是指碎片整理,如何整理呢?如果发现晓得内存块,GC忽略它们,如果发现大的,可用的连续内存块,GC把非垃圾对象移动到这里以压缩堆。

包含只想这些对象的指针的变量和CPU寄存器,现在都会变得无效,NextObjPtr也应重新指向托管堆的结尾。

第三部分—终结列表和F-reachable队列

说到终结列表要从某些不仅占用内存的对象说起,比如FileStream,它不仅占用内存资源,也在占用本地资源。

Finalize方法就是用于释放本地资源的方法。

那么这个终结列表用来做什么呢?微软当然不会画蛇添足,请仔细看好下面这段:

既占用内存资源,又占用本地资源的,在GC回收这样对象所占的内存时,仅仅回收内存时不够的,因为一定要调用Finalize方法来释放本地资源啊!强烈不建议在代码中我们手动Finalize,这需要堆Finalize的实现有相当深刻并且全面的理解。那么微软的GC是什么怎么来给我们执行的呢?这就用到了终结列表,为了一定要保证执行Finalize,在最初我们new操作符分配内存地时候,如果该对象的类型中定义了Finalize方法,那么将该对象的一个指针方法到终结列表当中,当此类对象在托管堆中判定为垃圾的时候,GC扫描终结列表,以查找这些对象的指针,该指针会从终结列表中移除,并追加到F-reachable队列。

那么这个队列干嘛的呢?我认为唯一的目的就是复活对象,并调用Finalize方法释放本地资源(如果对象是死的,我们无法调用其方法),调用方法的是一个微软定义好的优先级比较高的一个线程,听说这样做有很多好处。那么为什么放到F-reachable队列中就复活了?f(finalization)终结,reachable可达的。换言之,可将这个队列看做静态字段那样的一个跟。

第四部分—代的思想和原理

GC机制无论何时,都分为三代,0代,1代,2代。

代是什么,微软关于这个做了假设,新对象生存周期比较短,而老对象倾向于活的久一些。所在代越高的对象,存活的越久,所在代越低的对象,越容易被回收。

代就是托管堆中被分配的内存而已,也可以说把托管堆分成三部分吧?

0代初始的预算大小为256kb,当0代中的内存用完时,为新对象分配内存,0代内存不够用时,GC开始回收第一代,未被标记的对象当然回收,已标记的对象则这些对象提高一代,进入1代区域,与此同理,当一代内存已满时,回收1代,此时根对象也就是标记的对象提升至2代。

再次重点说一下三代预算大小分别为256KB,2MB,10MB,预算大小以提升性能为宜,预算越大,垃圾回收频率越低。再次注意的是,性能提升的理论源于开始的假设:新对象生存期较短,老对象倾向于活的久一些。请仔细看下面一段。

如果GC回收后,0代存活下来的对象很少,或者说回收的内存很多。0代预算可能会从256调整为128。代的分配空间减少,意味着回收频繁回收频繁,但GC所做的工作会减少,从而减小进程的工作集,最理想的状态是0代对象都是当做垃圾被回收,这样不必压缩内存,NextObjPtr指向0代起始处。这样来讲,最开始的假设是是成立的。

浅谈你感兴趣的 C# GC 机制底层的更多相关文章

  1. 浅谈你感兴趣的 CLR GC 机制底层

    本文内容是学习CLR.via C#的21章后个人整理,有不足之处欢迎指导. 昨天是1024,coder的节日,我为自己coder之路定下一句准则--保持学习,保持自信,保持谦逊,保持分享,越走越远. ...

  2. 浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6627260 在前面一篇文章浅谈Service ...

  3. 浅谈V8引擎中的垃圾回收机制

    最近在看<深入浅出nodejs>关于V8垃圾回收机制的章节,转自:http://blog.segmentfault.com/skyinlayer/1190000000440270 这篇文章 ...

  4. 浅谈JS异步轮询和单线程机制

    单线程特点执行异步操作 js是单线程语言,浏览器只分配给js一个主线程,用来执行任务(函数),但一次只能执行一个任务,这些任务就会排队形成一个任务队列排队等候执行.一般而已,相对耗时的操作是要通过异步 ...

  5. 【转】.NET(C#):浅谈程序集清单资源和RESX资源 关于单元测试的思考--Asp.Net Core单元测试最佳实践 封装自己的dapper lambda扩展-设计篇 编写自己的dapper lambda扩展-使用篇 正确理解CAP定理 Quartz.NET的使用(附源码) 整理自己的.net工具库 GC的前世与今生 Visual Studio Package 插件开发之自动生

    [转].NET(C#):浅谈程序集清单资源和RESX资源   目录 程序集清单资源 RESX资源文件 使用ResourceReader和ResourceSet解析二进制资源文件 使用ResourceM ...

  6. 浅谈 G1 GC 日志格式

    在 Java9 中,G1 GC 将成为默认的垃圾收集器,G1 垃圾收集器的关键特性之一是能够在不牺牲吞吐量的同时,限制 GC 暂停时间(即可以设置所需的最大停顿时间). 由于 G1 GC 正在逐渐成为 ...

  7. ? 这是个很好的问题。Go 当前的 GC 显然做了一些额外的工作,但它也跟其他的工作并行执行,所以在具有备用 CPU 的系统上,Go 正在作出合理的选择。请看 https://golang.org/issue/17969 结束语(Closing notes) 通过研究 Go 垃圾收集器,我能够理解 Go GC 当前结构的背景以及它如何克服它的弱点。Go发展得非常快。如果你对 Go感兴趣,最好继

    ? 这是个很好的问题.Go 当前的 GC 显然做了一些额外的工作,但它也跟其他的工作并行执行,所以在具有备用 CPU 的系统上,Go 正在作出合理的选择.请看 https://golang.org/i ...

  8. 【ASP.NET MVC系列】浅谈ASP.NET 页面之间传值的几种方式

    ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...

  9. 浅谈Java回收对象的标记和对象的二次标记过程_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 一.对象的标记 1.什么是标记?怎么标记? 第一个问题相信大家都知道,标记就是对一些已死的对象打上记号,方便垃圾收集器的 ...

随机推荐

  1. 为什么说Java中的随机数都是伪随机数?

    什么是伪随机数?  1.伪随机数是看似随机实质是固定的周期性序列,也就是有规则的随机. 2.只要这个随机数是由确定算法生成的,那就是伪随机,只能通过不断算法优化,使你的随机数更接近随机.   (随机这 ...

  2. Java-接口练习

    编写2个接口:InterfaceA和InterfaceB:在接口InterfaceA中有个方法voidprintCapitalLetter():在接口InterfaceB中有个方法void print ...

  3. struts2学习笔记之七:Result类型

    一:关于Struts2的type类型,也就是Result类型,他们都实现了共同的接口Result,都实现了execute方法 他们体现了策略模式,具体Result类型参见:struts-default ...

  4. maven install 读取jar包时出错;error in opening zip file

    错误信息: [INFO] ------------------------------------------------------------------------ [ERROR] Failed ...

  5. 每天一个linux命令(40):wc命令

    Linux系统中的wc(Word Count)命令的功能为统计指定文件中的字节数.字数.行数,并将统计结果显示输出. 1.命令格式: wc [选项]文件... 2.命令功能: 统计指定文件中的字节数. ...

  6. html学习记录之表格、表单基础

    ①编码:charset="utf-8": ​②描述及关键词:name="description":name="keywords": ③a标签 ...

  7. 转载:css3 content 生成内容

    本文地址:http://www.w3cplus.com/solution/css3content/css3content.html 这篇文章挺不错的,建议看一下. content一般和:before, ...

  8. CSS实战中经常出现的问题。

    如果你把这些当做文章来看,那你始终是学不会,而是应该当做手册来看,这些也是自己在写网站遇到的问题.转载请出处. 追梦子前端博客. 1. logo添加内容给h1设置text-index:-9999px的 ...

  9. poj 3321 Apple Trie

    /* poj 3321 Apple Trie 这道题的关键是如何将一个树建成一个一维数组利用树状数组来解题! 可以利用dfs()来搞定,我们在对一个节点深搜后,所经过的节点的数目就是该节点的子树的数目 ...

  10. java中的显示初始化和特定初始化

    public class Test{ public static void main(String[] args){ Child child = new Child(); } } class Pare ...