Welcome

首页 / 软件开发 / .NET编程技术 / .Net Discovery系列之四 深入理解.Net垃圾收集机制(下)

.Net Discovery系列之四 深入理解.Net垃圾收集机制(下)2011-01-19 博客园 缘清上一节给大家介绍了 .Net GC的运行机制,下面来讲下与GC相关的重要方法。

第二节.GC关键方法解析

1.Dispose()方法

Dispose可用于释放所有资源,包括托管的和非托管的,需要自己实现。

大多数的非托管资源都要求手动释放,我们应当为释放非托管资源公开一个方法,实现释放非托管资源的方法有很多种,实现IDispose接口的Dispose方法是最好的,这可以给使用你类库的程序员以明确的说明,让他们知道怎样释放你的资源;而且C#中用到的using语句快,也是在离开语句块时自动调用Dispose方法。

这里需要注意的是,如果基类实现了IDispose接口,那么它的派生类也必须实现自己的IDispose,并在其Dispose方法中调用基类中Dispose方法。只有这样的才能保证当你使用派生类实例后,释放资源时,连同基类中的非托管资源一起释放掉。

插曲:使用using与try+finally的区别

可以说2者没有任何区别,因为using只是编辑器级的优化,它与try+finally有着相同的作用,以下是一段使用using的代码,它在IL阶段也是以try+finally呈现的:

C#:

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
using (DataSet ds = new DataSet())
{
}
}
}

MSIL:
.method family hidebysig instance void Page_Load(object sender,class [mscorlib]System.EventArgs e) cil managed
{
// 代码大小 29 (0x1d)
.maxstack 2
.locals init ([0] class [System.Data]System.Data.DataSet ds,
[1] bool CS$4$0000)
IL_0000: nop
IL_0001: newobj instance void [System.Data]System.Data.DataSet::.ctor()
IL_0006: stloc.0
.try
{
IL_0007: nop
IL_0008: nop
IL_0009: leave.s IL_001b
} // end .try
finally
{
IL_000b: ldloc.0
IL_000c: ldnull
IL_000d: ceq
IL_000f: stloc.1
IL_0010: ldloc.1
IL_0011: brtrue.s IL_001a
IL_0013: ldloc.0
IL_0014: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0019: nop
IL_001a: endfinally
} // end handler
IL_001b: nop
IL_001c: ret
} // end of method _Default::Page_Load

但是,using的优点是,在代码离开using块时,using会自动调用Idispose接口的Dispose()方法。