Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.)

like image 986
mafu Avatar asked Aug 11 '10 12:08

mafu


People also ask

How many Finalizers can a class have?

A class can only have one finalizer. Finalizers cannot be inherited or overloaded. Finalizers cannot be called. They are invoked automatically.

When to use finalize vs dispose?

Finalize is the backstop method, called by the garbage collector when it reclaims an object. Dispose is the "deterministic cleanup" method, called by applications to release valuable native resources (window handles, database connections, etc.)

How Finalize method works in C#?

The Finalize method is used to perform cleanup operations on unmanaged resources held by the current object before the object is destroyed. The method is protected and therefore is accessible only through this class or through a derived class.

Which method notifies garbage collector not to call finalize?

Finalize method, is used to release unmanaged resources before an object is garbage-collected. If obj does not have a finalizer or the GC has already signaled the finalizer thread to run the finalizer, the call to the SuppressFinalize method has no effect.


2 Answers

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.

like image 79
OregonGhost Avatar answered Sep 30 '22 00:09

OregonGhost


If a finalizer throws an exception, other finalizers will not execute.

You can also suppress finalizers if you call SuppressFinalizer on the object.

From MSDN (Object.Finalize):

The Finalize method might not run to completion or might not run at all in the following exceptional circumstances:

  • Another finalizer blocks indefinitely (goes into an infinite loop, tries to obtain a lock it can never obtain and so on). Because the runtime attempts to run finalizers to completion, other finalizers might not be called if a finalizer blocks indefinitely.
  • The process terminates without giving the runtime a chance to clean up. In this case, the runtime's first notification of process termination is a DLL_PROCESS_DETACH notification.
like image 40
Oded Avatar answered Sep 30 '22 00:09

Oded