In the book Headfirst C#, I get the point of view that "it's not a good idea to serialize an object in its finalizer, since serialization requires the whole object tree to be in the heap, but you may end up with missing vital part of your program because some objects might’ve been collected before the finalizer ran."
My question is that since my object get a reference to others (that means there is at least one reference to other objects) , how could they be garbage-collected before my finalizer runs?
Because the garbage collector does not define any order of running finalizers, and doesn't care if your objects are finalized out of order.
By the time your finalizer runs, the GC has already decided that it and every object it references are unreachable, and thus all of those child objects will also be collected. Each of those objects is added to the finalizer queue, but there is no guarantee that the GC will handle them in any outwardly-sensible order.
That's one of the limitations of what you can do in a finalizer: you have to assume all of your child objects could have been destroyed already. The documentation for Object.Finalize calls this out explicitly:
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 been finalized when the finalizer of Object A starts.
The problem with finalizers is that they provide very few guarantees:
Eric Lippert has two great blog posts about this:
In any case, 99% of the classes you'll ever write should probably not have a finalizer at all. There are very few cases where they're actually necessary. If you need to perform cleanup after you're done using an object, implement IDisposable
instead, which at least you can control in a deterministic way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With