<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Chris Lyon's WebLog : GCHandles</title><link>http://blogs.msdn.com/clyon/archive/tags/GCHandles/default.aspx</link><description>Tags: GCHandles</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>The Truth About GCHandles</title><link>http://blogs.msdn.com/clyon/archive/2005/03/18/398795.aspx</link><pubDate>Fri, 18 Mar 2005 20:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:398795</guid><dc:creator>clyon</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/clyon/comments/398795.aspx</comments><wfw:commentRss>http://blogs.msdn.com/clyon/commentrss.aspx?PostID=398795</wfw:commentRss><description>&lt;p&gt;I've heard several people asking why GCHandle doesn't implement IDisposable, considering it wraps an unmanaged resource (a handle) and needs to be explicitly freed (using GCHandle.Free()). Before I explain the reason, I want to give a little background on GCHandles and their dangers. &lt;/p&gt; &lt;p&gt;What's a GCHandle? &lt;/p&gt; &lt;p&gt;A GCHandle is a struct that contains a handle to an object. It's mainly used for holding onto a managed object that gets passed to the unmanaged world to prevent the GC from collecting the object. You can also create a Pinned GCHandle to a managed object and retrieve the object's address in memory. &lt;/p&gt; &lt;p&gt;How are GCHandles dangerous? &lt;/p&gt; &lt;p&gt;When you create a new GCHandle, a new entry in the AppDomain's handle table is created. This entry is kept until the handle is freed (via GCHandle.Free()) or the AppDomain is unloaded. &lt;/p&gt; &lt;p&gt;Things get tricky if you were to make a copy of a GCHandle: &lt;/p&gt; &lt;p class="code"&gt;Object obj = new Object();&lt;br /&gt;GCHandle gch = GCHandle.Alloc(obj, GCHandleType.Normal);&lt;br /&gt;GCHandle gch2 = gch;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Since GCHandle is value type, gch2 has its own copy of the handle. You now have two handles that point to the same entry in the handle table. Unfortunately, since gch2 is a copy of –not a reference to– gch, anything that happens to gch doesn't happen to gch2. For example, calling gch.Free() will delete the entry from the handle table, but not update gch2, so gch2.IsAllocated will return true, but gch2.Target will be null. The same problem arises with casting to and from IntPtrs, and when GCHandles get boxed. Unlike double-freeing a single GCHandle, freeing the copy will NOT throw an InvalidOperationException. You have to be very careful not to double-Free your handles since this can corrupt the handle table. &lt;/p&gt; &lt;p&gt;Why don't GCHandles implement IDisposable? &lt;/p&gt; &lt;p&gt;One of the main purposes of IDisposable to avoid the use of finalizers. This is because finalizers are not run deterministically, and result in promoting a finalizable object a generation, effectively keeping in memory longer. Since GCHandle is a value type, it has no finalizer, and is not collected by the GC, so these problems are eliminated. Another other main use of IDisposable is to clean up unmanaged resources as soon as you are done with them. With a GCHandle, the resource is the handle which is cleaned up by calling GCHandle.Free(). If Free isn't called, the handle gets cleaned up when the appdomain is unloaded. &lt;/p&gt; &lt;p&gt;One of the side effects of having a struct implement IDisposable, is that users may be tempted to cast their GCHandles as IDisposable, which boxes the GCHandle into an IDisposable object on the heap, and the two GCHandles get out-of-sync. The same problem arises with the putting a disposable struct into a using block: &lt;/p&gt; &lt;p class="code"&gt;struct Test : IDisposable&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public bool disposed; // initialized to false&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void Dispose()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;disposed = true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void Foo()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Test t = new Test();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;using (t)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// do stuff&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (!t.disposed)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t.Dispose();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt; &lt;p&gt;t.disposed will return false, since it was a copy of t whose Dispose method was called. If t were a GCHandle, then the handle would be removed from the appdomain's handle table, and calling Free after the using would result in a double Free, even though IsAllocated would return true! &lt;/p&gt; &lt;p&gt;Remember, GCHandles are advanced structures, and one should be very careful to ensure they are cleaned up properly. Unfortunately, IDisposable makes it easy to get this wrong, so the BCL designers erred on the side of caution, and gave GCHandle a Free() method to use. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=398795" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/clyon/archive/tags/Dispose/default.aspx">Dispose</category><category domain="http://blogs.msdn.com/clyon/archive/tags/GCHandles/default.aspx">GCHandles</category></item><item><title>GCHandles, Boxing and Heap Corruption</title><link>http://blogs.msdn.com/clyon/archive/2004/09/17/230985.aspx</link><pubDate>Fri, 17 Sep 2004 18:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:230985</guid><dc:creator>clyon</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/clyon/comments/230985.aspx</comments><wfw:commentRss>http://blogs.msdn.com/clyon/commentrss.aspx?PostID=230985</wfw:commentRss><description>&lt;p&gt;A GCHandle is a struct used to hold onto a managed object to be used by unmanaged code.&amp;nbsp; With a GCHandle you can (among other things): &lt;ul&gt; &lt;li&gt;Prevent an object from being garbage collected if unmanaged code has the only live reference to it &lt;li&gt;Pin an object in memory, so it won’t be relocated in memory by the garbage collector &lt;li&gt;Get the memory address of the pinned object&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The last point is interesting.&amp;nbsp; When dealing with managed code, addresses of reference objects (objects allocated on the heap) are not constant.&amp;nbsp; As the GC tries to reclaim memory, it moves objects around in memory and compacts the heap.&amp;nbsp; If you’re P/Invoking into an unmanaged DLL, you may need to pass the address of some object.&amp;nbsp; That’s where GCHandles come in.&lt;/p&gt; &lt;p&gt;The syntax for allocating a pinned GCHandle is as follows (C# code):&lt;/p&gt; &lt;div class="code"&gt;Int[] arr = new int[10];&lt;br /&gt;GCHandle gch = GCHandle.Alloc(arr, GCHandleType.Pinned);&lt;/div&gt; &lt;p&gt;The above code pins arr in memory (so it won’t be moved), and creates a new GCHandle that “wraps” arr.&amp;nbsp; You can now get the address of arr using GCHandle.AddrOfPinnedObject.&lt;/p&gt; &lt;p class="aside"&gt;Note: you can only pin blittable types in memory (types that have the same representation in managed and unmanaged code).&amp;nbsp; Blittable types include primitive types and arrays.&lt;/p&gt; &lt;p&gt;The problem occurs when you accidentally misuse Alloc.&amp;nbsp; For example, I’ve seen code like this:&lt;/p&gt; &lt;div class="code"&gt;Object obj = new Object();&lt;br /&gt;GCHandle gch2 = GCHandle.Alloc(Marshal.SizeOf(typeof(obj)), GCHandleType.Pinned);&lt;/div&gt; &lt;p&gt;It looks like the developer tried to allocate a GCHandle with the same size as obj in memory.&amp;nbsp; So what does this code actually do?&lt;/p&gt; &lt;p&gt;Marshall.SizeOf returns an int that when passed to a method expecting an Object, is boxed into a newly heap-allocated Object.&amp;nbsp; So the new GCHandle obediently pins this new Object in memory.&amp;nbsp; Then when you pass gch2.AddrOfPinnedObject to your unmanaged code… trouble.&lt;/p&gt; &lt;p&gt;Consider an unmanaged method takes an array of ints, and increments each element.&amp;nbsp; You’ve passed it an address, and it dutifully increments each value it finds for the length of the array.&amp;nbsp; Congratulations, you’ve just corrupted memory.&lt;/p&gt; &lt;p&gt;If you’re lucky, this crashes the runtime right away.&amp;nbsp; If you’re unlucky, your app may continue to run and crash sometime in the future or your app’s data may be messed up.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=230985" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/clyon/archive/tags/GC/default.aspx">GC</category><category domain="http://blogs.msdn.com/clyon/archive/tags/GCHandles/default.aspx">GCHandles</category></item></channel></rss>