【框架设计】VS自动内存管理(垃圾回收集)

   VS自动内存管理(垃圾回收集)

概述:简述内存回收机制:应用程序调用new操作符创建对象时,在地址空间即托管堆不包含任何对象时,这时添加到托管堆上的对象称为第0代,第0代对象会被分被一个预算内存大小,假如256K,第0代对象假如有4个ABCD.并且AD为根.那么与AD有联系的所有对象都被CLR认可.当0代超出内存时,托管堆的NExtObjPtr指针地址开始对0代中的非根(BC对象)标记.然后将其清除.D对象内存将压缩.产生AD连续分配的内存,此时,该片段内存已经成为第1代.重新分配对象即为第0代,以此类推,垃圾回收由浅入深,即从0代到第3代(总共3代).这时当托管堆的内存满时.才需要执行垃圾收集,垃圾收集总共三种方式分别是:Dispose方法,Close方法和Finalize方法(不能显示调用,只能被碎片收集程序调用).以上为本人对垃圾回收机制总结,下面对重点问题剖析:

C#基础系列导航


  1. C#实现队列读写操作(一)
  2. 变化多端的列表(二)
  3. VS自动内存管理(垃圾回收集)(三)
  4. C#忽略基础知识点梳理(四)
  5. 什么是框架的接口(五)
  6. 程序集的加载与反射(六)
  7. CLR寄宿和应用程序域(七)
  8. 异常(八)

从托管堆中分配资源:

CLR要求所有资源从托管堆中分配,进程初始化完成后,CLR保留一片连续的地址空间,这段空间最初不对应任何物理内存,该地址空间又叫托管堆.托管堆中内存分配有一个叫着NextObjPtr的指针,该指针开始时被保留在地址空间首部作为基地址,随后有新对象产生即指向下一个地址,一直保留在下一个地址空间等待新对象内存分配.

空间地址分配由new关键符控制的,它操作编译器在相应方法的IL代码生成一个newobj指令.代码运行,其指令做以下操作:

1,计算基类总共字节数

2,计算对象开销所需要的字节数.每个对象有两个开销字段:类型对象指针和同步索引块

3,检查是否满足新对象分配所需字节,满足则提交物理内存

托管堆与非托管堆(C语言运行库的堆):都需要遍历一个链表数据结构,找到一片连续的内存,非托管堆连续创建几个对象,对象可能被分散在地址空间的各个角落.而托管代码在托管堆中,连续分配的对象可以保证连续在内存中.

垃圾收集算法:垃圾收集器通过检查托管堆中是否有应用程序不再使用对象来回收内存.整个检查步骤分为两大步:

一,标记阶段:垃圾回收器遍历线程中的所有根(静态字段,方法参数,局部变量,CPU寄存器),如果根引用一个对象,那么对向的同步索引块的索引字段被设置一位,即为标记.垃圾回收器一旦检查完根,堆中则包含一组已标记和未标记的对象,其中已标记的对象应用程序可以到达的对象,未标记的则不可以到达,被认为垃圾.

二,压缩阶段:垃圾回收器线性的遍历堆找到未标记的对象进行处理.那么被标记的小内存块向大内存块移动,最终形成连续区块.

使用终结操作来释放本地资源:

终结是CLR提供的一种机制,它允许对象在垃圾回收内存之前执行一些资源清理操作,任何包含本地资源的类型,例如(文件,网络连接,套接字,互斥体以及其他类型)都必须支持终结操作.本质上来说,对象使用一种Finalize方法.当垃圾回收器判定一个对象为可回收垃圾时,变调用Finalize方法.一般加~来定义Finalize方法,与析构函数定义一样。

使用SafeHander类型实现非托管代码间的互操作:

派生自SafeHander类很有用,可以保证垃圾回收机制执行本地资源可以得到释放。

导致Finalize方法调用的五大原因:

1,第0代对象充满:分配新对象是调用此方法回收内存

2,代码显示调用System.GC的静态方法Collect:代码显示请求CLR执行垃圾集

3,Windows报告内存不足:如果内存不足,则CLR强制执行垃圾收集,释放死亡对象,以减少进程大小

4,CLR卸载应用程序域:CLR认为其不存在根,所以执行垃圾收集

5,CLR关闭:进程终止,认为无根.

人工监视和控制对象的生存期:

CLR为每个应用程序域提供一个GC句柄表,该表允许程序域监视对象生存期,或者人工控制对象的生存期.当创建应用程序域时,该句柄表为空.调用GCHandle的静态方法Alloc时,需要监视对象引用GCHandleType(枚举类型)标记.GCHandletype定义如下:

weak:标记监视对象的生存期,应用程序域不可到达时监视.

WeakTrackResurrection:标记监视对象的生存期,应用程序域不可到达时监视.

Normal:标记监视对象的生存期,无根,对象还在内存时.

Pinned:标记监视对象的生存期,无根,对象还在内存时.

垃圾回收器利用GC句柄表的方法:

1.垃圾收集器标记所有可达对象.

2,垃圾收集器扫描GC句柄表查找所有标记为Weak的条目.弱weak的条目引用一个未标记的对象即垃圾,条目指针为空.

3,垃圾收集器扫描终结表,指针引用未标记对象,即应用程序不可达到对象。指针从终结表转移到终结可达队列,最终对象又变成可达对象。

4,垃圾收集器扫描GC句柄表查找标记WeakTrackResearch的条目。

5,垃圾收集器压缩内存,挤出不可到达的内存。

对象的代:

代是CLR垃圾收集器的一种机制,它存在唯一提高应用程序性能。托管堆中分配地址空间一共分为3代

监视垃圾收集:访问系统监视器控件的最简单的方式就是运行PerMon.exe。

原文地址:https://www.cnblogs.com/baiboy/p/c3.html