系列二:资源管理(概论)

1.垃圾收集器(GC)控制着托管内存。但是我们需要对非托管代码进行处理(数据库连接,文件句柄,GDI+对象,COM对象等)

 

2.垃圾收集器是运行在一个单独的线程中来移除程序中不再使用的内存。并且还会压缩托管堆,使得空闲内存能集中在一个连续的区域。

 

3.对于非托管资源我们需要在类型中定义一个终结器,以此来确保释放这些系统资源。在对象的内存被回收之前,系统会调用终结器,这样我们可以在终结器中编写我们的代码来释放该对象占有的非托管资源。值得注意的是对象的终结器是在对象成为垃圾之后调用的,但是在内存归还之前,但是我们无法精确的控制“不再使用对象”和“执行终结器”这2个事件之间的关系。

 

4.当GC发现某个对象是垃圾但是需要终结器时,它还不能直接从内存上删除这个对象。首先,它要调用终结器,但终结器的调用不是在垃圾回收器的同一个线程上运行的。取而代之的是,GC不得不把对象放置到终结器队列中,让另一个线程让执行所有的终结器。GC继续它自己的工作,从内存上移除其它的垃圾。在下一个GC回收时,那些被终结器了的对象才会再从内存上移除。

 

5.Net回收器定义了一种称为“代龄”的机制来优化。代可以帮助GC来很快的标识那些看上去看是垃圾的对象。所有从上一次GC回收后开始创建的对象称为第0代对象,所有那些经过一次GC回收后还存在的对象称为第1代对象。所有那些经过2次或者2次以上GC回收后还存在的对象称为第2代对象。代龄的目的就是用来区分临时变量以及一些应用程序的全局变量。第0代对象绝大部分是临时的变量。成员变量,以及一些全局变量很快会成为第1代对象,最终成为第2代对象。GC通过限制检测第1以及第2代对象的频度来优化它的工作。每一次GC循环都检测第0代对象,大概10次GC周期才会检查第0和第一代对象,大概100次GC周期才检查一次第0,1,2代对象。让我们考虑一下:一个须要终结器的对象可能要比一个不用终结器的对象在内存里多待上9个GC回收循环。如果它还没有终结器,它将会移到第2代对象。在第2代对象中,一个可以生存上100个GC循环直到下一个第2代集合。

 

6.记得一个垃圾回收器负责内存管理的托管环境的最大好处:内存泄漏,其它指针的相关的问题将不再存在。非内存资源迫使你要使用终结器来确保清理非内存资源。终结器会对你的应用程序性能产生一些影响,但你必须使用它们来防止资源泄漏。通过实现IDisposable接口并且使用它可以避免终结器在垃圾回收器上造成的性能损失。

 

 

 

posted @ 2011-01-05 00:05  yu_liantao  阅读(286)  评论(0编辑  收藏  举报