GC管理 总结

面试经常会遇到GC管理的问题,每次问到的时候都会如实回答,没研究过,然后大家就知道结果是什么了。今天特别看了关于GC的教程,视频说的挺好的,我也做了如下几个笔记,如果哪里写的有问题,也请提出来一起探讨。

GC的主要功能:GC主要负责回收内存,对于非托管资源只能进行辅助性的回收。

GC处理的步骤:GC启动  Mark(标记),Compact(压缩),Update(更新)

1. 扫描并标记-找到垃圾对象
2. 压缩-回收垃圾对象
3. 更新指针
 
GC的特点:标记-压缩算法
   1.  分配速度快,回收速度慢
   2.  确保空闲内存区域连续,避免内存碎片
   3.  对象地址不稳定(过一段时间垃圾回收器就会搬移一次,也因此C#不能输出对象的地址)
 
一. 资源管理与分类:托管资源与非托管资源
     托管资源:托管堆内存
     非托管资源:文件句柄,数据库链接,本地内存等
 
二. 内存的分配与管理
      .net线式分配,间歇性压缩搬移对象内存(快,无碎片)
      C++链式分配,对象地址稳定不变(慢,有碎片)
 
三. 内存的销毁
     .net由系统在非确定时刻(启发式算法)收集(慢)
     c++由程序员在确定时刻收集(即调用delete)(快)
 
分代式垃圾收集
 
一. CLR执行一个单独的线程来负责垃圾收集器,这时它会挂起当前所有线程
 
二. 分代式垃圾收集:区分对象代龄基于以下假设:
     对象越新,其生存周期越短
     对象越老,其生存周期越长
 
三. 8/2原则
      GC收集一部分对象的“性价比”要高于一个对象和收集所有对象的效率
 
四. 每个托管堆对象分配一个代龄
     0代对象限额:256k(垃圾对象)
     1代对象限额:2M
     2代对象限额:10M
     GC是先回收0代,然后在根据大小回收1,2代。
 
IDisposable接口定义:定义一种释放分配的资源的方法。
 
析构函数与构造函数比较

构造函数定义: 构造函数是和类同名,没有返回值。

析构函数定义: 在类名前加~,也没有返回值。

构造函数执行过程:构造函数上在对象创建时执行。

析构函数执行过程:析构函数是在程序结束时执行,一般时候析构函数里面写的都是一些资源回收之类的东西,不过C#的析构函数的调用机制和C++不同.并不能保证每次都会调用.所以最好不要利用C#的析构函数来回收资源。

 
析构器两大缺点(本质会编译成Finalize)
1. 拖大了对象的代龄(处理方法在Close回收方法中写入GC.SupperssFinalize(this),那么程序会认为没有写析构方法)
2. 回收资源不及时(写一个Close方法自动回收)
析构器编写是怕程序员忘记调用close方法了。
只要继承IDisposable ,这个类就是资源类,就要调用Dispose()
 
终结操作:Finalize方法
1. 非托管资源的清理: GC主要负责回收内存,对于非托管资源只能进行辅助性的回收。
2. C#析构器与Object.Finalize虚方法
3.如果判断一个类需要终结操作?该类或者其某个父类(Object除外)实现了析构器(重写了Finalize)
4. GC非确定性执行:终结操作的执行时间分析
5.垃圾收集器并不保证终结操作的顺序
   避免两个对象的终结操作有顺序的依赖
6.长弱引用于短弱引用
   利用弱引用缓存对象
 
 
Dispos设计模式
一. 终结操作(就是析构器)给对象带来的性能负担
     1. 如果一个对象需要终结操作,GC会因此而提升其代龄,从而延迟收集对象。
     2. 终结操作本身是非确定性的,是潜在资源泄漏
 
二. 确定性清理:Dispose设计模式
      1. Idisposable.DisPose()接口方法
      2. 析构器(Finalize方法)
      3. 在Dispose方法中调用GC.SuppressFinalize(避免Finalize被GC调用  这个方法就是当作没写析构器)
 
三. using语句与Dispose模式
 

 

对技术有兴趣的朋友可以加入群:245507606  好好学习,天天向上.......

posted @ 2016-08-02 18:17  筱畢_C#  阅读(304)  评论(0编辑  收藏  举报