Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Garbage collection Guarantees

What guarantees are the for the garbage collector?

From my research I have managed to find:

  • If there is still a reference to the memory it will not be garbage collected
  • If there is no reference:
    • When it is GC is non deterministic
    • When the GC kicks in the finalizer will be run before memory is released.
    • There is no guarantee about the order of Finalizers (so do not assume parent will be run before child).

But what I really want to know is:

Is there a guarantee that all memory will eventually be garbage collected and the finalizer (destructor) run on the object (assuming the program exited nicely). For example an application with no memory pressure when it eventually exits will it force the GC to go find all objects and make sure the finalizer (destructor) is called (including static member variables)?

I did find a quote on this page: http://www.c-sharpcorner.com/UploadFile/tkagarwal/MemoryManagementInNet11232005064832AM/MemoryManagementInNet.aspx

In addition, by default, Finalize methods are not called for unreachable objects when an application exits so that the application may terminate quickly.

But I am not sure how authoritative this quote is.

I also found documentation on: CriticalFinalizerObject

like image 384
Martin York Avatar asked Jan 07 '10 01:01

Martin York


1 Answers

Is there a guarantee that all memory will eventually be garbage collected and the finalizer (destructor) run on the object (assuming the program exited nicely).

No. From the Object.Finalize documentation it is clear that finalizers may not be invoked if

  • Some other finalizers don't finish properly:

    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.

  • Some other finalizers create more finalizable objects, making it impossible to finalize all finalizable objects:

    The runtime continues to Finalize objects during shutdown only while the number of finalizable objects continues to decrease.

  • Some other finalizers throw exceptions:

    If Finalize or an override of Finalize throws an exception, and the runtime is not hosted by an application that overrides the default policy, the runtime terminates the process and no active try-finally blocks or finalizers are executed. This behavior ensures process integrity if the finalizer cannot free or destroy resources.

That being said, there are more reasons why you wouldn't want to use finalizers unless strictly necessary.

  • They slow down the garbage collector (even making it possible to slow it down so much that memory is not reclaimed as fast as it is used up).
  • They run on another thread, bringing multi-threading issues into play.
  • They're not executed in a deterministic order.
  • They can resurrect objects which were already finalized (and which won't be finalized again unless explicitly re-registered for finalization).
like image 142
Wim Coenen Avatar answered Sep 22 '22 22:09

Wim Coenen