Click here to Skip to main content
15,881,812 members
Home / Discussions / C#
   

C#

 
GeneralRe: Finalization and Performance Pin
George_George1-May-08 3:47
George_George1-May-08 3:47 
GeneralRe: Finalization and Performance Pin
Christian Graus1-May-08 3:56
protectorChristian Graus1-May-08 3:56 
GeneralRe: Finalization and Performance Pin
George_George1-May-08 4:10
George_George1-May-08 4:10 
GeneralRe: Finalization and Performance Pin
N a v a n e e t h1-May-08 6:07
N a v a n e e t h1-May-08 6:07 
GeneralRe: Finalization and Performance Pin
George_George1-May-08 21:19
George_George1-May-08 21:19 
GeneralRe: Finalization and Performance Pin
N a v a n e e t h1-May-08 22:59
N a v a n e e t h1-May-08 22:59 
GeneralRe: Finalization and Performance Pin
George_George2-May-08 2:43
George_George2-May-08 2:43 
AnswerRe: Finalization and Performance PinPopular
Mike Dimmick1-May-08 6:04
Mike Dimmick1-May-08 6:04 
To save time in garbage collection, .NET implements a 'generational' garbage collector. When a GC is complete, .NET remembers the first address it will give out to new objects. When the next GC occurs, to save time, it will only scan from that remembered address, unless doing so won't give up enough free memory. It's most likely that the objects that have been created most recently are no longer required, as many objects have very short lifetimes. Those that have been used less frequently are more likely to have very long lifetimes.

In fact .NET remembers not one address but two, creating three 'generations' of objects. The objects from the start of memory to the first address are 'generation 2', those between the two addresses are 'generation 1', and those after the second address are 'generation 0'. If an object survives a collection of its generation, it is promoted one generation. If generation 0 collection doesn't yield enough space, generation 1 is collected. Only if both don't yield enough space will generation 2 be collected.

The GC collects by marking every object that is still referenced by 'roots', such as thread stacks and static objects. It follows every reference from those objects and marks everything. Once everything that's referenced is marked, it then 'sweeps' the memory from first object to last and anything that isn't marked is cleaned up.

It's at this point that anything that isn't marked requires finalization - has a finalizer, and GC.SuppressFinalize hasn't been called - is added to the finalization queue. The GC then follows all the references from those objects and marks them to ensure that anything still needed by an object that requires finalization is kept, in case the finalizer needs to use those referenced objects.

Finally, once everything needing finalization is queued up, GC <i>compacts</i> the heap, moving every object (that isn't <i>pinned</i>) down in memory so it's next to the previous one with no gaps. It has to rewrite all the references to do this, but the result is hopefully a nice big empty block at the end of the heap.

There's a background thread, the finalizer thread, whose responsibility it is to process the finalization queue. Only this thread ever calls finalizer methods, and it does it asynchronously with respect to GC. The queue is considered a root so future collections can't collect this memory until the objects' finalizers have been run and they're no longer marked as needing finalization. So the objects that need finalization end up being promoted at least one generation, which means that they'll only be cleaned up when gen 0 collection doesn't give enough space or when the heuristics call for a collection of an older generation.

The trouble with the finalizer thread is that a small error in a finalizer can end up blocking it. That stops all finalizers running, and then the GC can't free anything that needed finalizing.

Best practice is to make very small wrapper classes for managing unmanaged resources, that pretty much just manage that resource. Don't allow any references to other objects. Implement the IDisposable interface and a finalizer, and a Dispose(bool disposing) method. In the Dispose method, clean up the unmanaged resource and call GC.SuppressFinalize(this) to stop the infrastructure having to queue the object for finalization.

In the rest of your code, ensure that you call Dispose on any object that implements it. Use the <code>using</code> block where possible, dispose member variables in the class's Dispose override, dispose of anything else once you're done with it. That means, if the class has implemented the dispose pattern properly, the object should never end up in the finalizer. It's a backstop, there if you forget, but in my view, a running finalizer is a bug.


DoEvents: Generating unexpected recursion since 1991

GeneralRe: Finalization and Performance Pin
N a v a n e e t h1-May-08 6:41
N a v a n e e t h1-May-08 6:41 
GeneralRe: Finalization and Performance Pin
Guffa1-May-08 9:29
Guffa1-May-08 9:29 
GeneralRe: Finalization and Performance Pin
George_George1-May-08 21:27
George_George1-May-08 21:27 
GeneralRe: Finalization and Performance Pin
N a v a n e e t h1-May-08 23:06
N a v a n e e t h1-May-08 23:06 
GeneralRe: Finalization and Performance Pin
George_George2-May-08 2:44
George_George2-May-08 2:44 
GeneralRe: Finalization and Performance Pin
Guffa2-May-08 1:54
Guffa2-May-08 1:54 
GeneralRe: Finalization and Performance Pin
N a v a n e e t h2-May-08 2:35
N a v a n e e t h2-May-08 2:35 
GeneralRe: Finalization and Performance Pin
Guffa2-May-08 17:42
Guffa2-May-08 17:42 
GeneralRe: Finalization and Performance Pin
N a v a n e e t h2-May-08 20:35
N a v a n e e t h2-May-08 20:35 
GeneralRe: Finalization and Performance Pin
George_George2-May-08 2:47
George_George2-May-08 2:47 
GeneralRe: Finalization and Performance Pin
N a v a n e e t h1-May-08 23:08
N a v a n e e t h1-May-08 23:08 
GeneralRe: Finalization and Performance Pin
Guffa2-May-08 1:57
Guffa2-May-08 1:57 
GeneralRe: Finalization and Performance Pin
George_George1-May-08 21:28
George_George1-May-08 21:28 
GeneralRe: Finalization and Performance Pin
Pete O'Hanlon1-May-08 8:31
mvePete O'Hanlon1-May-08 8:31 
GeneralMagnificent Pin
Luc Pattyn1-May-08 9:11
sitebuilderLuc Pattyn1-May-08 9:11 
GeneralRe: Magnificent Pin
Spacix One1-May-08 9:49
Spacix One1-May-08 9:49 
GeneralRe: Magnificent Pin
Luc Pattyn1-May-08 10:20
sitebuilderLuc Pattyn1-May-08 10:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.