杨存伟
(西南大学 计算机科学与技术系,重庆 402460)
在.NET中,内存资源分为托管资源和非托管资源,其中托管资源指的是.NET 可以自动进行回收的资源,主要是指托管堆上分配的内存资源[1]。GC 类中包含了垃圾回收相关的方法,其中GC.KeepAlive 是其中一个较为特别的方法,它利用编译器和运行时的特性,阻止对象过早被回收。
示例1
在类Value中,实现了IDisposable中的Dispose方法,在类OuterClass 中,析构方法调用类成员i 的Dispose 方法来释放资源。


在Main 函数中,生成了一个Outerclass 的对象,变量名为outer,并将outer.i 作为参数传递给Do函数。outer.i 作为参数传入之后,不存在对Outerclass 的对象的使用,因此垃圾回收器认为该对象已经无用,而outer.i 是有效的。从这时起到程序运行结束的任何时刻,垃圾回收器都有可能执行一次回收(回收Outerclass 的对象)。在垃圾回收器调用outer 的析构方法后,outer.i 已经执行了Dispose 方法,从而Do 函数中对outer.i 的操作可能是无效的,造成程序出错(图1)。

图1 不调用GC.KeepAlive 方法时程序的执行流程
若在Do(outer.i)后添加“GC.KeepAlive(outer)”,则Do 方法调用之后依然有对outer 的使用,保证了在调用Do 方法的时候,OuterClass 的对象不会被垃圾回收器回收(图2)[2]。

图2 调用GC.KeepAlive 方法时程序的执行流程
Microsoft 对该方法的官方实现为:

属性(Attribute)是用于在运行时传递程序中各种元素(类、结构体、方法等)的行为信息的声明性质的标签,它添加元数据,如编译器指令和注释、描述、方法、类等其他信息。
.NET 提供了两种类型的特性:预定义特性和自定义特性。MethodImplAttribute 和Reliability-Contract 都属于预定义特性[3]。
MethodImplAttribute 属性指定了一个方法是怎样编译和执行的。……