深入了解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的代码,大家可以参考.

