Free mag vol1 | Page 547

CHAPTER 13  UNDERSTANDING OBJECT LIFETIME call instance void [mscorlib]System.Object::Finalize() IL_0019: nop IL_001a: endfinally } // end handler IL_001b: nop IL_001c: ret } // end of method MyResourceWrapper::Finalize If you then tested the MyResourceWrapper type, you would find that a system beep occurs when the application terminates, given that the CLR will automatically invoke finalizers upon AppDomain shutdown. static void Main(string[] args) { Console.WriteLine("***** Fun with Finalizers *****\n"); Console.WriteLine("Hit the return key to shut down this app"); Console.WriteLine("and force the GC to invoke Finalize()"); Console.WriteLine("for finalizable objects created in this AppDomain."); Console.ReadLine(); MyResourceWrapper rw = new MyResourceWrapper(); }  Source Code The SimpleFinalize project is included under the Chapter 13 subdirectory. Detailing the Finalization Process Not to beat a dead horse, but always remember that the role of the Finalize() method is to ensure that a .NET object can clean up unmanaged resources when it is garbage-collected. Thus, if you are building a class that does not make use of unmanaged memory (by far the most common case), finalization is of little use. In fact, if at all possible, you should design your types to avoid supporting a Finalize() method for the very simple reason that finalization takes time. When you allocate an object onto the managed heap, the runtime automatically determines whether your object supports a custom Finalize() method. If so, the object is marked as finalizable, and a pointer to this object is stored on an internal queue named the finalization queue. The finalization queue is a table maintained by the garbage collector that points to each and every object that must be finalized before it is removed from the heap. When the garbage collector determines it is time to free an object from memory, it examines each entry on the finalization queue and copies the object off the heap to yet another managed structure termed the finalization reachable table (often abbreviated as freachable, and pronounced “effreachable”). At this point, a separate thread is spawned to invoke the Finalize() method for each object on the freachable table at the next garbage collection. Given this, it will take, at the very least, two garbage collections to truly finalize an object. The bottom line is that while finalization of an object does ensure an object can clean up unmanaged resources, it is still nondeterministic in nature, and due to the extra behind-the-curtains processing, considerably slower. 488