- If the object's type defines a Finalize method, a pointer to the object is placed on the finalization list just before the type's instance constructor is called.
- The finalization list is an internal data structure controlled by the garbage collector.
- Each entry in the list points to an object that should have its Finalize method called before the object's memory can be reclaimed.
- Even though System.Object defines a Finalize method, the CLR knows to ignore it; that is, when constructing an instance of a type, if the type's Finalize method is the one inherited from System.Object, the object isn't considered finalizable. One of the derived types must override Object's Finalize method.
- When a garbage collection occurs, some objects are determined to be garbage. The garbage collector scans the finalization list looking for pointers to these objects. When a pointer is found, the pointer is removed from the finalization list and appended to the freachable queue.
- The freachable queue is another of the garbage collector's internal data structures.
- A special high-priority CLR thread is dedicated to calling Finalize methods.
- When the freachable queue is empty, this thread sleeps. But when entries appear, this thread wakes, removes each entry from the queue, and then calls each object's Finalize method.
- So if an object is in the freachable queue, the object is reachable and is not garbage.
- The next time the garbage collector is invoked, it will see that the finalized objects are truly garbage because the application's roots don't point to it and the freachable queue no longer points to it either. The memory for the object is simply reclaimed.
- Two garbage collections are required to reclaim memory used by objects that require finalization. In reality, more than two collections will be necessary because the objects get promoted to another generation.