Why is it not a good idea to serialize an object in its finalizer?
Asked Answered
F

2

6

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?

Flashlight answered 29/8, 2015 at 12:19 Comment(3)
I'm not sure about your question but keep in mind that there is no guarantee whatsoever that your finalizer will run in the first place.Kingship
Related question hereSoever
Serializing an object when it's essentially in the process of being snuffed-out is arguably bad design. That it is at the mercy of unknowns is equally startingSchoolmaster
G
7

The problem with finalizers is that they provide very few guarantees:

  • they're not guaranteed to ever run
  • you can't predict when they will run
  • when they do run, it's possible that some objects they reference have already been finalized, so your object might not be in a valid state

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.

Gosling answered 29/8, 2015 at 12:28 Comment(0)
C
8

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.

Careless answered 29/8, 2015 at 12:27 Comment(0)
G
7

The problem with finalizers is that they provide very few guarantees:

  • they're not guaranteed to ever run
  • you can't predict when they will run
  • when they do run, it's possible that some objects they reference have already been finalized, so your object might not be in a valid state

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.

Gosling answered 29/8, 2015 at 12:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.