Search code examples
.netgarbage-collectionfinalizer

Are .net finalizers always executed?


Are finalizers guaranteed to be executed in .NET at some point (spare power outages and the like)? I know how GC works and that it is nondeterministic when exactly they'll run.

(The search did not display good answers, so I'm adding this question in high expectation of a merge with the not-so-easy-to-discover actual answers. Apart from that, I already know the answer and am going to add it after a few days in case nobody mentioned it.)


Solution

  • Finalizers may actually be never executed, as Raymond Chen explains. Kind of funny that this question is asked during his annual CLR week, just two days after he explained it :)

    For the lazy ones, the (or rather, one) conclusion is:

    A correctly-written program cannot assume that finalizers will ever run.

    If you are wondering whether you can rely on finalizers, this is already everything you have to know: Don't rely on finalizers.

    As Raymond Chen also states in the linked article:

    Finalizers are a safety net, not a primary means for resource reclamation.

    If you're looking for how to release resources, have a look at the Disposable pattern.


    A finalizer may not run, for example, if:

    • Another finalizer throws an exception.
    • Another finalizer takes more than 2 seconds.
    • All finalizers together take more than 40 seconds.
    • An AppDomain crashes or is unloaded (though you can circumvent this with a critical finalizer (CriticalFinalizerObject, SafeHandle or something like that)
    • No garbage collection occurs
    • The process crashes

    (Note: The time values may have changed over time, but were certainly true some time ago.)

    I guess there are a lot more things that can cause finalizers to never run. The bottom line is, other than the quote from Mr. Chen, that finalizers are a safety net that decrease the impact of bugs, because for example resources are released sometime, which is better than never, if you forget to do it explicity.