Monday, June 30, 2008

Avoid Writing Finalize Method in C#

Say, a C# class, SomeClass, is defined as follows. If you think a destructor is defined in the class and it's a good practice to have a destructor in a class to clean up resources. Well, according to Jeffrey Richter's CLR via C#, you are wrong.

public class SomeClass

{

~SomeClass() { ... }

}

First, there is no destructor in C#, only Finalize method. The behavior of ~SomeClass() in C# is different from that in C++. That function will execute when CLR performs garbage collection. On the other hand, in C++, it is deterministic. When one deletes an instance of SomeClass, ~SomeClass() is executed. Although the goal of both methods in both languages is the same, that is, releasing resources, but the execution timing is different. Both have the same syntax with different semantics.

Second, for classes referencing managed resources, the book suggests one avoid writing a Finalize method for the reasons I quote below.

  • Finalizable objects take longer to allocate because pointers to them must be placed on the finalization list.
  • Finalizable objects get promoted to older generations, which increases memory pressure and prevents the object's memory from being collected at the time the garbate collector determines that the object is garbage. In addition, all objects referred to directly or inderectly by this object get promoted as well.
  • Finalizable objects cause your application to run slower since extra processing must occur for each object when collected.

Writing Finalize method to release managed resources actually adds overheads on the CLR at object construction and collection. Plus, you can't control when the Finalize method will execute. If you stop writing Finalize method in your class, your code will be simpler and performance will be better.

For types referencing unmanaged resources, one should implement IDisposable interface to deterministically dispose of resources. That is, in the Dispose method, one calls the Win32 CloseHandle function to release native resources, and then invokes GC.SuppressFinalize method as there is no need for the object's Finalize method to execute.

Further readings:

1 comment:

Unknown said...

This is a great site for references regarding any kind of programming in .net or oracle etc. Its really appreciating that Ken Wu uses programming in his day today financial problems.
sap support package implementation