一. why 为何使用GC程序员
一、提升了软件开发的抽象度;算法
二、程序员能够将精力集中在实际的问题上而不用分心来管理内存的问题;数据库
三、可使模块的接口更加的清晰,减少模块间的偶合;函数
四、大大减小了内存人为管理不当所带来的Bug;性能
五、使内存管理更加高效。优化
二 .net中的GC机制.net
限制:线程
1. GC不能释放非托管资源。对象
2.GC并非实时的,这将会形成系统性能瓶颈和不肯定性。因此提供了IDisposable接口,程序员可使用Dispose方法显式的释放非托管资源。接口
GC注意事项:
一、只管理内存,非托管资源,如文件句柄,GDI资源,数据库链接等还须要用户去管理。
二、循环引用,网状结构等的实现会变得简单。GC的标志-压缩算法能有效的检测这些关系,并将再也不被引用的网状结构总体删除。
三、GC经过从程序的根对象开始遍从来检测一个对象是否可被其余对象访问,而不是用相似于COM中的引用计数方法。
四、GC在一个独立的线程中运行来删除再也不被引用的内存。
五、GC每次运行时会压缩托管堆。
六、你必须对非托管资源的释放负责。能够经过在类型中定义Finalizer来保证资源获得释放。
七、对象的Finalizer被执行的时间是在对象再也不被引用后的某个不肯定的时间。注意并不是和C++中同样在对象超出声明周期时当即执行析构函数
八、Finalizer的使用有性能上的代价。须要Finalization的对象不会当即被清除,而须要先执行Finalizer.Finalizer,不是在GC执行的线程被调用。GC把每个须要执行Finalizer的对象放到一个队列中去,而后启动另外一个线程来执行全部这些Finalizer,而GC线程继续去删除其余待回收的对象。在下一个GC周期,这些执行完Finalizer的对象的内存才会被回收。
九、.NET GC使用"代"(generations)的概念来优化性能。代帮助GC更迅速的识别那些最可能成为垃圾的对象。在上次执行完垃圾回收后新建立的对象为第0代对象。经历了一次GC周期的对象为第1代对象。经历了两次或更多的GC周期的对象为第2代对象。代的做用是为了区分局部变量和须要在应用程序生存周期中一直存活的对象。大部分第0代对象是局部变量。成员变量和全局变量很快变成第1代对象并最终成为第2代对象。
十、GC对不一样代的对象执行不一样的检查策略以优化性能。每一个GC周期都会检查第0代对象。大约1/10的GC周期检查第0代和第1代对象。大约1/100的GC周期检查全部的对象。从新思考Finalization的代价:须要Finalization的对象可能比不须要Finalization在内存中停留额外9个GC周期。若是此时它尚未被Finalize,就变成第2代对象,从而在内存中停留更长时间。