深入了解C#系列:谈谈C#中垃圾回收与内存管理机制(4)
1.try
2
{
3 IL_0003: nop
4 IL_0004: newobj instance void [MemoryManagement]MemoryManagement.FrankClassWithDispose::.ctor()
5 IL_0009: stloc.0
6 IL_000a: ldloc.0
7 IL_000b: callvirt instance void [MemoryManagement]MemoryManagement.FrankClassWithDispose::DoSomething()
8 IL_0010: nop
9 IL_0011: nop
10 IL_0012: leave.s IL_0028
11 } // end .try
12 finally
13
{
14 IL_0014: nop
15 IL_0015: ldloc.0
16 IL_0016: ldnull
17 IL_0017: ceq
18 IL_0019: stloc.s CS$4$0000
19 IL_001b: ldloc.s CS$4$0000
20 IL_001d: brtrue.s IL_0026
21 IL_001f: ldloc.0
22 IL_0020: callvirt instance void [MemoryManagement]MemoryManagement.FrankClassWithDispose::Dispose()
23 IL_0025: nop
24 IL_0026: nop
25 IL_0027: endfinally
26 } // end handler
27 IL_0028: nop
28 IL_0029: newobj instance void [MemoryManagement]MemoryManagement.FrankClassWithDispose::.ctor()
29 IL_002e: stloc.1
30 .try
31
{
32 IL_002f: nop
33 IL_0030: nop
34 IL_0031: leave.s IL_0045
35 } // end .try
36 finally
37
{
38 IL_0033: ldloc.1
39 IL_0034: ldnull
40 IL_0035: ceq
41 IL_0037: stloc.s CS$4$0000
42 IL_0039: ldloc.s CS$4$0000
43 IL_003b: brtrue.s IL_0044
44 IL_003d: ldloc.1
45 IL_003e: callvirt instance void [mscorlib]System.IDisposable::Dispose()
46 IL_0043: nop
47 IL_0044: endfinally
48 } // end handler
49
Using 语句有同样的效果,来实现非托管对象资源的释放。这点在面试中也会经常遇到,Using关键字的用法有哪几种等等类似的问题。基本理想的答案都是除了引用命名空间,和命名空间设置别名外,就是这个用法实现如try finally块一样作用的对非托管对象资源的回收。只是一种简便的写法。
当你用Dispose方法释放未托管对象的时候,应该调用GC.SuppressFinalize。如果对象正在终结队列(finalization queue),GC.SuppressFinalize会阻止GC调用Finalize方法。因为Finalize方法的调用会牺牲部分性能。如果你的Dispose方法已经对委托管资源作了清理,就没必要让GC再调用对象的Finalize方法(MSDN)。附上MSDN的代码,大家可以参考.