Garbage collectors are incredible things, the ideas are really simple but then the tricks used to optimise them (removing stop-the-world etc) are pretty magical.
When they interplay with JITs, everything gets even more complex and fascinating.
This is actually not a very helpful answer, even though it contains lots of interesting technical detail, because it fails to point out that the questioner shouldn't be asking this question.
In general, it's not a good idea to use GC-triggered finalizers the same way you would use destructors in C++. They aren't guaranteed to be called at any particular time, or even to be called at all. Use try ... finally instead.
Just about the only valid use of a GC-triggered finalizer is to release a native resource associated with the object (a native heap object, a file descriptor, etc.).
Actually, that's what the using statement and IDisposable is for (which is just a try/finally in disguise). Use Dispose to clean up, which has to be invoked explicitly or via using. And call Dispose in the finalizer as well to safeguard against accidental resource leaks. Since Dispose is supposed to be idempotent that won't cause trouble usually.
Admittedly, I didn't even read the question and just thought the answer was quite interesting, regardless of the context.
5 comments
[ 2.6 ms ] story [ 24.3 ms ] threadWhen they interplay with JITs, everything gets even more complex and fascinating.
In general, it's not a good idea to use GC-triggered finalizers the same way you would use destructors in C++. They aren't guaranteed to be called at any particular time, or even to be called at all. Use try ... finally instead.
Just about the only valid use of a GC-triggered finalizer is to release a native resource associated with the object (a native heap object, a file descriptor, etc.).
Admittedly, I didn't even read the question and just thought the answer was quite interesting, regardless of the context.
http://ericlippert.com/2013/06/10/construction-destruction/