在.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会找到一块大的连续区域,将未被回收的对象合并到这块大的对象里。
哈哈哈:接下来的听后续吧。。。下周会继续。。