此文是帮助arbtaystpw童鞋解惑.
GC的定义:
GC如其名,就是垃圾收集,当然这里仅就内存而言。Garbage Collector(垃圾收集器,在不至于混淆的情况下也成为GC)以应用程序的root为基础.
GC实现原理:
通过识别它们是否被引用来确定哪些对象是已经死亡的、哪些仍需要被使用。已经不再被应用程序的root或者别的对象所引用的对象就是已经死亡的对象,即所谓的垃圾,需要被回收。这就是GC工作的原理
为了实现这个原理,GC有多种算法。比较常见的算法有Reference Counting,Mark Sweep,Copy Collection等等。目前主流的虚拟系统.NET CLR,Java VM和Rotor都是采用的Mark Sweep算法
具体算法,我也不太了解.这里就不说了!
先上代码:
.NET的GC机制有这样两个问题:
第一,GC只能回收内存中的托管对象资源,对于非托管对象例如:数据库连接,文件句柄关于很多直接和硬件打交道的资源,GC是不能涉及的。
第二,GC并不是实时性的,这将会造成系统性能上的瓶颈和不确定性,因此.Net中GC会在某一个时间点去回收垃圾.
一.静态变量是否被GC回收
static string name = "张三";
GC.Collect();//此方法就是调用GC的回收方法
WeakReference wek = new WeakReference(name);//这个是弱引用类,IsAlive判断该引用对象是否存活
Console.WriteLine("静态变量是存活:" + wek.IsAlive);
输出结果为:True
二.被引用的对象是否被GC回收
List<Person> persons = new List<Person>();
for (int i = 0; i < 9000; i++ )
{
Person p = new Person();
}
//Person对象的实例被List<Person>的实例引用
GC.Collect();
WeakReference wek = new WeakReference(persons);
Console.WriteLine("被引用的变量是存活:" + wek.IsAlive);
输出结果为:True
三.没有被引用的对象是否被GC回收
Person p = new Person();//创建一个没有被引用的Person对象的实例
WeakReference wek = new WeakReference(p);
GC.Collect();
Console.WriteLine("没有被引用的变量是否存活:" +wek.IsAlive);
输出结果为:True
解析:为什么没有回收呢?是因为GC并不是实时性的,这将会造成系统性能上的瓶颈和不确定性,因此.Net中GC会在某一个时间点去回收垃圾,这个对象一定将被回收。
第三,关于非托管对象,如文件句柄,数据库连接等等,如何回收呢?
上面都说到GC只能回收内存中的托管对象资源,对于非托管对象例如:数据库连接,文件句柄关于很多直接和硬件打交道的资源,GC是不能涉及的
所以.Net有了IDisposable接口,IDisposable接口定义了Dispose方法,这个方法用来供程序员显式调用以释放非托管资源。使用using语句可以简化资源管理。
using(){}自动帮我们调用Dispose 方法,和try{}catch(){}finally{p.Dispose()}差不多
class Person : IDisposable
{
public void SayHello()
{
Console.WriteLine("Hello");
}
public void Dispose()
{
Console.WriteLine("释放资源");
}
}
Person p = new Person();
using (p) {
p.SayHello();
}
总结:
* 非托管内存中的资源类,一般需要实现IDesposable接口
* 使用using(){},相当于try{}catch(){}finally{p.Dispose();}
* 使用了using 作用域,会自动去调用IDisposable的实现方法
* IDisposable的实现方法可以帮助调用Close的关闭方法。 |