views:

61

answers:

1

If I implement a destructor in a class, Foo, instances of Foo are tracked closely on the finalization queue. When an instance of Foo is garbage collected, I understand that the CLR sees the entry in the finalization queue and gives that object special treatment by moving the object off the heap and into the finalization reachable table. Then... nothing else happens for that garbage collection cycle?

Will finalize() always be called during the next garbage collection cycle?

Why isn't finalize called immediately after copying my object to the freachable table? (this seems like extra unnecessary complexity)

+1  A: 

The finalizer queue is there to simplify things; it would be more complex without it. When the GC runs, no managed code must be executed - else all analysis that the GC had made might be void if user code runs in the middle.

So when the GC runs, finalization must be deferred, instead of getting executed right away. Running it in a separate thread minimizes the time that the VM requires exclusive access to all threads, and increases the potential for concurrent activities.

Martin v. Löwis
Understood. But why doesn't the garbage collector just fire off the Finalize() threads when it is finished with the cycle? Why wait for the next cycle?
Robert Venables
Why do you think it does not do that? When an object is finalizable, but otherwise unreachable, it gets added to the freachable queue. There, the finalizer thread will pick it up right away after the garbage collection finishes.
Martin v. Löwis
Andrew Troelsen said "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 very least two garbage collections to truly finalize an object" (p191 - Pro C# with .NET 3.0)
Robert Venables
I don't have the book in front of me, but I believe it to be wrong or misunderstood. The objects get finalized right after GC completes. However, their memory is only reclaimed at the next GC, hence it takes two GC cycles to truly release the memory of an object that is finalizable.
Martin v. Löwis