A splat of all my blathering.

Monday, April 12, 2004

.NET Garbage Collection of Unmanaged Objects 

Some very interesting articles on problems with the GC and unmanaged objects. They gave me some insight into proper handling of non-memory unmanaged resources (like handles) in .NET.

Lifetime, GC.KeepAlive, handle recycling
TSS.NET Article: Garbage Collection and Interoperability in .NET
GC.KeepAlive Method
Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework
Garbage Collection—Part 2: Automatic Memory Management in the Microsoft .NET Framework

I found some interesting replies to one of the articles above. It so happens that some readers looked into some of the claims in this article further and found them left wanting. An "almost" heated discussion ensued over the conclusions that the author drew. In particular, one reader took issue with the claim that the object was not referenced and therefore needed the GC.KeepAlive call.

"The problem you experienced must be related to something else. I really don't understand how adding GC.KeepAlive(h) solved the problem..."

One of the follow-up postings contained a few more links to even more interesting articles on this topic. These are particularly relevent to those of us designing managed classes and even more so if those classes are wrapping unmanaged "things". One link includes a quiz and a reference to a tool called CLR SPY that can be used to help debug related problems.

// This code has a bug!
public static void Main ()
// Open the key for read-only access
RegistryKey key = Registry.LocalMachine.OpenSubKey(
Console.WriteLine("Install root: " +

I found the answers to the quiz very revealing.

"When the current instance gets collected as the PInvoke call to RegQueryValueEx is initiated, RegCloseKey ends up being called before the unmanaged implementation of RegQueryValueEx executes. By the time the RegQueryValueEx API processes the handle, the handle is invalid! This problem is easy to introduce in any managed classes that wrap unmanaged handles. Yet the time window for failure can be so small that it would usually take a really long time for you to discover the bug."

In particular, I found it interesting that part of the solution includes the correct use of the IDisposable pattern.

Posted at 4/12/2004 02:50:00 PM |
Comments: Post a Comment

This page is powered by Blogger. Isn't yours?