{"id":23165,"date":"2007-03-21T01:17:00","date_gmt":"2007-03-21T01:17:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/maoni\/2007\/03\/21\/hes-live-hes-live-not-hes-live\/"},"modified":"2021-10-04T16:33:34","modified_gmt":"2021-10-04T23:33:34","slug":"hes-live-hes-live-not-hes-live","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/hes-live-hes-live-not-hes-live\/","title":{"rendered":"He\u2019s live\u2026 he\u2019s live not\u2026 he\u2019s live\u2026"},"content":{"rendered":"<p><P class=\"MsoNormal\"><FONT face=\"Verdana\">I was making some code changes today and thought this was interesting to share. As you know, the WeakReference class has a getter and a setter method to get and set the Target which is what the weakref points to. See <SPAN lang=\"EN\"><A href=\"http:\/\/blogs.msdn.com\/maoni\/archive\/2004\/12\/19\/327149.aspx\"><FONT color=\"#800080\">Using GC Efficiently \u2013 Part 3<\/FONT><\/A> <\/SPAN>for more details on WeakReference.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">Note that the code below is only for illustration purposes \u2013 it is not necessarily what\u2019s in the production code.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">So let\u2019s say the code used to look like this in the WeakReference class:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><SPAN>internal IntPtr m_handle;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>public<\/SPAN><SPAN> Object Target <\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>{<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>get <\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>{<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>IntPtr h = m_handle;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><SPAN>if<\/SPAN> (IntPtr.Zero == h)<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><SPAN>return<\/SPAN> <SPAN>false<\/SPAN>;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>Object o = GCHandle.InternalGet(h);<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>h = Thread.VolatileRead(ref m_handle);<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>GC.KeepAlive (<SPAN>this<\/SPAN>);<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><SPAN>return<\/SPAN> (h == IntPtr.Zero) ? null : o;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>}<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>&#8230;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>}<\/SPAN><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">m_handle is the weak GCHandle that we create to implemente the weakref funtionality. It\u2019s a weak handle that points to the object that you want your weakref object to point to. <\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">The problem is <\/FONT><SPAN>Thread.VolatileRead<\/SPAN><FONT face=\"Verdana\"> kind of a heavy weight thing &#8211; not very performant (there was a reason why we used this API in the first place\u2026not necessarily a good one but it\u2019s what we ended up with).<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">First of all let\u2019s take a look at the old code. Notice that we have a <\/FONT><SPAN>GC.KeepAlive<\/SPAN><FONT face=\"Verdana\"> in there. Why would we do that? I mean if during the call of <\/FONT><SPAN>Thread.VolatileRead<\/SPAN><FONT face=\"Verdana\">, the weakref object is dead and its finalizer sets m_handle to 0, we\u2019d just read 0. That\u2019s fine right? <\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">But imagine this code:<\/FONT><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>Object o = <SPAN>new<\/SPAN> Object(); <\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>while<\/SPAN><SPAN> (<SPAN>true<\/SPAN>) <\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>{<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>WeakReference wr = <SPAN>new<\/SPAN> WeakReference (o); <\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN><SPAN>if<\/SPAN> (wr.Target == null) <\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>{<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>&#8230;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>}<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>}<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>o.GetHashCode(); <\/SPAN><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">We know that o is live during the while loop which means it would be really nice if wr.Target is null (some would consider it a bug if wr.Target was ever null in this case). If we didn\u2019t have the KeepAlive, object wr could be considered dead as soon as its address is passed in to the <SPAN>&nbsp;<\/SPAN><\/FONT><SPAN>Thread.VolatileRead<\/SPAN><FONT face=\"Verdana\"> call as the argument. So then h could be 0 and we\u2019d return null. So we want to make sure that if the object the weakref points to is guaranteed to be live during the getter call, you will always get back that object instead of null.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">Wouldn\u2019t that achieve the same effect since m_handle is an instance data member and if it\u2019s used, the *this* object should be kept alive where the last statement is?<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">Well, actually since m_handle is not a volatile, jit could generate some code that stores the value of m_handle in a register so it will not need to read the value of m_handle again when it\u2019s at that last statement. <\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">Another interesting thing about this code is that it does the IntPtr.Zero check after it first read the value of m_handle. But how can m_handle be 0? m_handle is only set to 0 in the WeakReference class\u2019s finalizer code. If we are already KeepAlive-ing the weakref object, it means the object should be live therefore by definition the finalizer should have not been run, right?<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">Well, unfortunately there is a case where m_handle can be 0 while we are in the getter which is when the getter is called in an object\u2019s finalizer. Imagine you have this object hireachy: <\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><SPAN>public<\/SPAN><SPAN> <SPAN>class<\/SPAN> ObjectA<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>{<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>WeakReference wr;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN><SPAN>public<\/SPAN> ObjectA(WeakReference wr0)<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>{<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>&#8230;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>wr = wr0;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>}<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>&#8230;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN><SPAN>public<\/SPAN> ~ObjectA() <\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>{<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>&#8230;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><SPAN>if<\/SPAN> (wr.Target == null)<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>{<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>&#8230;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>}<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>&#8230;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>}<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>}<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>ObjectA a = <SPAN>new<\/SPAN> ObjectA();<\/SPAN><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">When a is not used anymore, at some point both a\u2019s and wr0\u2019s finalizer (assuming a is the only object that contains a reference to wr0) will be put on the finalize queue.<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">Now if a\u2019s finalizer gets to run first, we are fine \u2018cause when we are in wr0\u2019s getter, m_handle is still valid. But if wr0\u2019s finalizer gets to run first, then when a\u2019s finalizer is run, m_handle is already set to 0. Of course as we\u2019ve been saying that a finalizer should do no more than releasing native resources, this shouldn\u2019t be a common scenario. <\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">So, the idea is to change <\/FONT><SPAN>m_handle<\/SPAN><FONT face=\"Verdana\"> to volatile and eliminate the need for calling <\/FONT><SPAN>Thread.VolatileRead<\/SPAN><FONT face=\"Verdana\">. The resulting code looks like this:<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><SPAN>internal <SPAN>volatile<\/SPAN> IntPtr m_handle;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>public<\/SPAN><SPAN> Object Target <\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>{<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>get <\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>{<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>IntPtr h = m_handle;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><SPAN>if<\/SPAN> (IntPtr.Zero == h)<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><SPAN>return<\/SPAN> null;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN>Object o = GCHandle.InternalGet(h);<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/SPAN><SPAN>return<\/SPAN> (m_handle == IntPtr.Zero) ? null : o;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>}<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>&nbsp;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN><SPAN>&nbsp;&nbsp;&nbsp; <\/SPAN>&#8230;<\/SPAN><\/P>\n<P class=\"MsoNormal\"><SPAN>}<\/SPAN><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">Notice that KeepAlive is gone because we are reading a volatile value which means the weakref object will be kept alive though out the getter. We still need to check if h is IntPtr.Zero at the beginning because we are still subject to be called from another object\u2019s finalizer. <\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">&nbsp;<\/FONT><\/P>\n<P class=\"MsoNormal\"><FONT face=\"Verdana\">Some people don\u2019t use volatile\u2019s in fear of losing performance \u2018cause volatile\u2019s can\u2019t be optimzed by the compiler. In reality though, if you read the volatile into a local when you need to access it frequently and that you are fine with the cached value, no reason to be afraid of using volatile\u2019s.<\/FONT><\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was making some code changes today and thought this was interesting to share. As you know, the WeakReference class has a getter and a setter method to get and set the Target which is what the weakref points to. See Using GC Efficiently \u2013 Part 3 for more details on WeakReference. &nbsp; Note that [&hellip;]<\/p>\n","protected":false},"author":3542,"featured_media":58792,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685],"tags":[3010,3011],"class_list":["post-23165","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","tag-general","tag-maoniposts"],"acf":[],"blog_post_summary":"<p>I was making some code changes today and thought this was interesting to share. As you know, the WeakReference class has a getter and a setter method to get and set the Target which is what the weakref points to. See Using GC Efficiently \u2013 Part 3 for more details on WeakReference. &nbsp; Note that [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/23165","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/3542"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=23165"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/23165\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=23165"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=23165"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=23165"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}