Garbage Collector(垃圾收集器)以应用程序的root为基础,遍历应用程序在Heap上动态分配的所有对象,通过识别它们是否被引用来确定哪些对象是已经死亡的哪些仍需要被使用。已经不再被应用程序的root或者别的对象所引用的对象就是已经死亡的对象,即所谓的垃圾,需要被回收。这就是GC工作的原理。
为了实现这个原理,GC有多种算法。比较常见的算法有Reference Counting,Mark Sweep,Copy Collection等等。目前主流的虚拟系统.net CLR,Java VM和Rotor都是采用的Mark Sweep算法。
托管堆中存放引用类型对象,因此GC的内存管理的目标主要都是引用类型对象。
一个对象的生命周期简单概括就是:创建>使用>释放,在.NET中一个对象的生命周期:
1.标记:根据应用程序根指针Root遍历堆上的每一个引用对象,对于还在使用的对象(可达对象)进行标记
2.清除:针对所有无引用对象进行清除,针对普通对象直接回收内存,而对于实现了终结器的对象(实现了析构函数的对象)需要单独回收处理。清除之后,内存就会变得不连续了,就是步骤3的工作了。
3.压缩:把剩下的对象转移到一个连续的内存,因为这些对象地址变了,还需要把那些Root跟指针的地址修改为移动后的新地址。
.NET中提供释放非托管资源的方式主要是:Finalize() 和 Dispose()。
常用的大多是Dispose模式,实现IDisposable接口,Dispose需要手动调用,在.NET中有两中调用方式:
//方式1:显示接口调用 SomeType st1=new SomeType(); //do sth st1.Dispose(); //方式2:using()语法调用,自动执行Dispose接口 using (var st2 = new SomeType()) { //do sth }
using只是一种语法形式,本质上还是try…finally的结构
它作用就是用来释放非托管资源,由GC来执行回收,因此可以保证非托管资源可以被释放。
它是来自System.Object中受保护的虚方法Finalize,无法被子类显示重写,也无法显示调用。
所有实现了终结器(析构函数)的对象,会被GC特殊照顾,GC的终止化队列跟踪所有实现了Finalize方法(析构函数)的对象。
原文:https://www.cnblogs.com/lqyy/p/11028416.html