分享

CLR.gc

 ZGJson 2012-07-10

1.深入探索.NET框架内部了解CLR如何创建运行时对象 
http://www.microsoft.com/china/MSDN/library/netFramework/netframework/JITCompiler.mspx?mfr=true

2.CLR 全面透彻解析--大型对象堆揭秘
http://msdn.microsoft.com/zh-cn/magazine/cc534993.aspx

3.CLR探索系列
http://www.cnblogs.com/lbq1221119/archive/2008/02/20/1059152.html

4.深入理解.NET 的JIT编译方式

http://blog.csdn.net/tanliyoung/archive/2007/05/04/1596021.aspx

 


5.垃圾回收技术的发展
http://www.cnblogs.com/jillzhang/archive/2006/11/03/549281.html



6.CRL via C#
newobj(IL)的步骤 
  • 计算类型及其基类所有字段所需要的字节总数
  • 在前边字节的基础上加上两个开销数量:类型对象指针(4Byte),同步索引块(4Byte)。
  • CLR检查物理内存是否足够。如果足够,则新对象被放置在NewObjPtr所指的托管堆位置.接着构造器被调用(NewObjPtr被传递给this)。NewObjPtr指向下一处可用内存。newobj指令返回新对象地址。

CLR与C运行时内存分配的对比: 
  • C运行时操作链表,查找足够大的内存块并返回,之后修改链表。连续分配对象的内存可能不连续。
  • CLR的内存分配则只是简单的地址加新对象的偏移量,效率极高,甚至堪比线程堆栈。连续分配对象的内存连续。

连续内存的优势: 
  • 进程的工作集相对较小
  • 方法中使用的对象也更可能同时在CPU缓存中驻留

其它一些说明: 
  • GC保证了托管堆的内存无限的假设。
  • new操作符通过检查NewObjPtr+Offset是否超界来触发GC(基于上边的简单模型)。
  • GC只有在第0代对象充满时才会触发。
  • GC有相当的性能开销。

GC算法: 
  • 根:程序中的一个存储位置,包含了一个指向引用类型对象的(托管堆)内存地址。可以是static字段、方法参数或局部变量。注意,只有引用类型的变量才是根,值类型变量不是。
  • GC不会手机根所指向的对象(存在引用)。
  • GC可以遍历线程调用栈,检查每个方法的内部表来确定方法内部的根。
  • GC在所有类型对象中迭代执行以得到静态字段的根组。
  • GC开始执行时,假设各个对象都可以收集(没有标记)。
  • 之后,GC开始标记(marking)操作:如果发现根引用了一个对象,就在该对象的同步块索引字段上标记一位(可能递归根所引用的对象,如果存在的话)。
  • 继续标记下一个根,如果已经被标记,则停止次根的标记活动(提高效率并避免环)
  • 线性遍历垃圾(未被标记的)内存块,直到找到较大的连续内存块,则把之前的非垃圾对象搬移到该地址以压缩托管堆。
  • 搬移对象需要修改指向原对象地址的CPU寄存器内容。
  • 使NewObjPtr指向最后一个非垃圾对象之后。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多