.NET 垃圾回收

Posted on 2010-04-27 23:43  pumeifen  阅读(1735)  评论(3编辑  收藏  举报

在.NET 中自动垃圾管理 是垃圾回收器来做的。GC自动完成对托管堆的全权管理,然后把所有的事情都交给GC来做。

对于.NET 程序员及基于性能安全考虑有必要对GC工作原理,执行过程进行深层次探讨。

垃圾回收机制从以下几个方面来讨论:

1,什么样的对象GC认为 是垃圾呢。

2,GC如何来回收垃圾呢。

3,GC何时来回收垃圾呢。

4,GC回收之后要操作些什么呢。

好。那我们一一来揭晓谜底吧。

l   什么样的对象被GC认为是垃圾呢?

一个对象成为垃圾:那就说明这个对象不在被任何使用。

其实每个对象 都有一组指针,针指向拖管堆的存储位置,由JIT编译器与CLR运行时维护根指针列表,包括全

局变量、静态变量、局部变量和寄存器指针等

代码
class A { private B objB; public A(B o) { objB = o; } ~A() { Console.WriteLine("Destory A."); }}
class B { private C objC; public B(C o) { objC
= o; } ~B() { Console.WriteLine("Destory B."); } }
class C { ~C() { Console.WriteLine(
"Destory C."); } }
public class Test_GCRun
{
public static
void Main()
{ A a
= new A(new B(new C())); //强制执行垃圾回收 GC.Collect(0); GC.WaitForPendingFinalizers();
}

 

在上述执行中,当创建类型A的对象a时,在托管堆中将新建类型B的实例(假设表示为objB)和类型C的实例(假设表示为objC),

并且这几个对象之间保存着一定的联系。而局部变量a则相当于一个应用程序的根,假设其在托管堆中对应的实例表示为objA,则当前的引用关系可以

l 何时回收? 
垃圾收集器周期性的执行内存清理工作,一般在以下情况出现时垃圾收集器将会启动: 
(1)内存不足溢出时,更确切地应该说是第0代对象充满时。
(2)调用GC.Collect方法强制执行垃圾回收。
(3)Windows报告内存不足时,CLR将强制执行垃圾回收。
(4)CLR卸载AppDomain时,GC将对所有代龄的对象执行垃圾回收。
(5)其他情况,例如物理内存不足,超出短期存活代的内存段门限,运行主机拒绝分配内存等
作为.NET开发人员的我们不必要自己写任何代码来管理整个Application 中各个对象的生命周期,CLR知道何时去执行垃圾收集工作来
满足application 的内存需求,当GC释放内存之前它会检查是否要执行非拖管资源的清理工作.Microsoft 强烈不建议通过GC.collect方法来强制回收垃圾,,这样会扰乱GC垃圾回收的工作原理.
只有明确有大对象不在引用时,才可以用GC.collect 来释放空间
2,回收之后它又会做什么呢。。。
GC回收之后中,会留下很多对象的空洞,为避免托管堆的碎片,会压缩托管堆,进行重新分配,就像我们经常执行碎片整理一样。具体操作:GC会找到一块大的连续区域,将未被回收的对象合并到这块大的对象里。
哈哈哈:接下来的听后续吧。。。下周会继续。。