Finalize()
 
This method is automatically called after an object becomes inaccessible, unless the object has been exempted from finalization by a call to SuppressFinalize. During shutdown of an application domain, Finalize is automatically called on objects that are not exempt from finalization, even those that are still accessible. Finalize is automatically called only once on a given instance, unless the object is re-registered using a mechanism such as ReRegisterForFinalize and GC.SuppressFinalize has not been subsequently called.

Every implementation of Finalize in a derived type must call its base type's implementation of Finalize. This is the only case in which application code is allowed to call Finalize.

Finalize operations have the following limitations:

  • The exact time when the finalizer executes during garbage collection is undefined. Resources are not guaranteed to be released at any specific time, unless calling a Close method or a Dispose method.
  • The finalizers of two objects are not guaranteed to run in any specific order, even if one object refers to the other. That is, if Object A has a reference to Object B and both have finalizers, Object B might have already finalized when the finalizer of Object A starts.
  • The thread on which the finalizer is run is unspecified.

The Finalize method might not run to completion or might not run at all in the following exceptional circumstances:

  • Another finalizer blocks indefinitely (goes into an infinite loop, tries to obtain a lock it can never obtain and so on). Because the runtime attempts to run finalizers to completion, other finalizers might not be called if a finalizer blocks indefinitely.
  • The process terminates without giving the runtime a chance to clean up. In this case, the runtime's first notification of process termination is a DLL_PROCESS_DETACH notification.

The runtime continues to Finalize objects during shutdown only while the number of finalizable objects continues to decrease.

If Finalize or an override of Finalize throws an exception, and the runtime is not hosted by an application that overrides the default policy, the runtime terminates the process and no active try-finally blocks or finalizers are executed. This behavior ensures process integrity if the finalizer cannot free or destroy resources.


Dispose()
A type's Disposemethod should release all the resources that it owns. It should also release all resources owned by its base types by calling its parent type's Dispose method. The parent type's Dispose method should release all resources that it owns and in turn call its parent type's Dispose method, propagating this pattern through the hierarchy of base types. To help ensure that resources are always cleaned up appropriately, a Dispose method should be callable multiple times without throwing an exception.

There is no performance benefit in implementing the Dispose method on types that use only managed resources (such as arrays) because they are automatically reclaimed by the garbage collector. Use the Dispose method primarily on managed objects that use native resources and on COM objects that are exposed to the .NET Framework. Managed objects that use native resources (such as the FileStream class) implement the IDisposable interface.
A Dispose method should call the SuppressFinalize method for the object it is disposing. If the object is currently on the finalization queue, SuppressFinalize prevents its Finalize method from being called. Remember that executing a Finalize method is costly to performance. If your Dispose method has already done the work to clean up the object, then it is not necessary for the garbage collector to call the object's Finalize method.

 

IDisposable

Close()



GC.KeepAlive()

KeepAlive 方法的目的是确保对对象的引用存在,该对象有被垃圾回收器过早回收的危险。这种现象可能发生的一种常见情形是,当在托管代码或数据中已没有对该对象的引用,但该对象仍然在非托管代码(如 Win32 API、非托管 DLL 或使用 COM 的方法)中使用。另一种过早发生垃圾回收的情形是,在一个方法中创建并使用一个对象。此时,当对对象的某个成员的调用仍在执行时,可能会对该对象进行回收。
此方法引用 obj,从而使该对象从例程开始到调用此方法的那个位置(按执行顺序)均不符合进行垃圾回收的条件。在 obj 必须可用的指令范围的结尾(而不是开头)编写此方法的代码。
KeepAlive 方法除了延长作为参数传递的对象的生存期之外,不会执行任何操作,也会不产生任何其他副作用。


。。
Summary
类型的 Dispose 方法应释放它拥有的所有资源。它还应该通过调用其父类型的 Dispose 方法释放其基类型拥有的所有资源。该父类型的 Dispose 方法应该释放它拥有的所有资源并同样也调用其父类型的 Dispose 方法,从而在整个基类型层次结构中传播此模式。若要确保始终正确地清理资源,Dispose 方法应该可以被多次调用而不引发任何异常。
Finalize (在C#中就是析构函数,在VB中是使用Finalize关键字)和 Dispose 都是释放资源,Finalize 隐式释放资源,Dispose 显式释放资源。Finalize 是对象不可访问后自动被调用的,Dispose 是类使用者调用的。
对于类设计者:

  1. Finalize 和 Dispose 释放的资源应该相同(除托管资源外),这样即使类使用者在没有调用 Dispose 的情况下,资源也会在 Finalize 中得到释放。
  2. Dispose 中应该调用 GC.SuppressFinalize 方法,这样类使用者调用了 Dispose 后,就不会自动调用 Finalize 了,因为调用 Dispose 后没有必要再执行 Finalize。
  3. Finalize 不应为 public。

对于类使用者:
有 Dispose 方法存在时,应该调用它,因为 Finalize 释放资源通常是很慢的。也就是说,对于类使用者,我们只需要调用 Dispose 就可以了,不需要关注 Finalize,因为 Finalize 通常不是 public 的。如果类使用者没有调用 Dispose 方法,Finalize 是释放资源的最后防线。当然这些都是建立在类设计者遵照上述规则设计的前提下。
GC.KeepAlive 延长对象的生存周期,即使现在没有引用指向这个对象。

Reference:
http://msdn.microsoft.com/zh-cn/library/system.object.finalize(VS.80).aspx