<?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>He’s live… he’s live not… he’s live…</title><link>http://blogs.msdn.com/b/maoni/archive/2007/03/20/he-s-live-he-s-live-not-he-s-live.aspx</link><description>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 – Part 3 for</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>re: He’s live… he’s live not… he’s live…</title><link>http://blogs.msdn.com/b/maoni/archive/2007/03/20/he-s-live-he-s-live-not-he-s-live.aspx#2651263</link><pubDate>Tue, 15 May 2007 18:24:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2651263</guid><dc:creator>nativecpp</dc:creator><description>&lt;p&gt;Thanks for the clarification.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2651263" width="1" height="1"&gt;</description></item><item><title>re: He’s live… he’s live not… he’s live…</title><link>http://blogs.msdn.com/b/maoni/archive/2007/03/20/he-s-live-he-s-live-not-he-s-live.aspx#2649247</link><pubDate>Tue, 15 May 2007 16:20:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2649247</guid><dc:creator>Maoni Stephens</dc:creator><description>&lt;p&gt;nativecpp, JIT is allowed to extend the lifetime of any local to the end of the method. The C# FAQ you mentioned is incorrect. For example, JIT doesn't track all locals if there are too many (of course most methods do fall under the &amp;quot;not too many locals&amp;quot; case). &lt;/p&gt;
&lt;p&gt;The point is you shouldn't count on JIT tracking the locals preciously. If you want to make sure a local is dead in the middle of a method you should manually set it to null. Most of the time you don't really need to do this - I would only do this if I have an object ref that associates with a lot of resources and there's a long way to go till end of the method.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2649247" width="1" height="1"&gt;</description></item><item><title>re: He’s live… he’s live not… he’s live…</title><link>http://blogs.msdn.com/b/maoni/archive/2007/03/20/he-s-live-he-s-live-not-he-s-live.aspx#2548655</link><pubDate>Fri, 11 May 2007 18:52:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2548655</guid><dc:creator>nativecpp</dc:creator><description>&lt;p&gt;My other thought was that what happened when GC occurs at&lt;/p&gt;
&lt;p&gt;m &amp;nbsp;= null; &amp;nbsp;// gc got triggered here&lt;/p&gt;
&lt;p&gt;Does JIT think m is still rooted ? Or does it have a special logic to ignore this assignment and therefore m will be considered as candidate for GC ???&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2548655" width="1" height="1"&gt;</description></item><item><title>re: He’s live… he’s live not… he’s live…</title><link>http://blogs.msdn.com/b/maoni/archive/2007/03/20/he-s-live-he-s-live-not-he-s-live.aspx#2528250</link><pubDate>Thu, 10 May 2007 22:03:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2528250</guid><dc:creator>nativecpp</dc:creator><description>&lt;p&gt;Yes. You are right that it is JIT not GC :-((&lt;/p&gt;
&lt;p&gt;One of the C# FAQs (&lt;a rel="nofollow" target="_new" href="http://blogs.msdn.com/csharpfaq/archive/2004/03/26/97229.aspx"&gt;http://blogs.msdn.com/csharpfaq/archive/2004/03/26/97229.aspx&lt;/a&gt;) stated that there is no need to set to NULL. And yet there are some who state it should set to NULL. I always thought there is no need to set to NULL for local variables as mentioned in the FAQ. There is time when you need to set to NULL as Rico stated in the comments (&lt;a rel="nofollow" target="_new" href="http://blogs.msdn.com/ricom/archive/2003/12/04/41281.aspx"&gt;http://blogs.msdn.com/ricom/archive/2003/12/04/41281.aspx&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;That is why I am confused :-((&lt;/p&gt;
&lt;p&gt;I know that you are not in JIT team. But, I thought JIT would traverse at least to the end of function block and therefore would know if the local var is reachable or NOT when GC occurs.&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2528250" width="1" height="1"&gt;</description></item><item><title>re: He’s live… he’s live not… he’s live…</title><link>http://blogs.msdn.com/b/maoni/archive/2007/03/20/he-s-live-he-s-live-not-he-s-live.aspx#2510908</link><pubDate>Thu, 10 May 2007 00:53:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2510908</guid><dc:creator>Maoni Stephens</dc:creator><description>&lt;p&gt;dal, the point is you shouldn't need to worry about the object lifetime yourself (most of the time anyway) 'cause JIT will do a correct analysis and keep things that need to be live live. &lt;/p&gt;
&lt;p&gt;nativecpp, yes, JIT (not GC :) this is not GC's job)will try very hard to determine when something is not used anymore it can be considered dead *before* it reaches the end of the scope. But it can't guarantee that as soon as something is not used anymore it can always immediately discover that. You can help JIT by settings refs to null so JIT knows immediately it can be considered dead.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2510908" width="1" height="1"&gt;</description></item><item><title>re: He’s live… he’s live not… he’s live…</title><link>http://blogs.msdn.com/b/maoni/archive/2007/03/20/he-s-live-he-s-live-not-he-s-live.aspx#2345625</link><pubDate>Tue, 01 May 2007 02:03:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2345625</guid><dc:creator>nativecpp</dc:creator><description>&lt;p&gt;I meant // m is NOT referenced anymore&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2345625" width="1" height="1"&gt;</description></item><item><title>re: He’s live… he’s live not… he’s live…</title><link>http://blogs.msdn.com/b/maoni/archive/2007/03/20/he-s-live-he-s-live-not-he-s-live.aspx#2345546</link><pubDate>Tue, 01 May 2007 02:00:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2345546</guid><dc:creator>nativecpp</dc:creator><description>&lt;p&gt;Hi Maoni,&lt;/p&gt;
&lt;p&gt;I was told that it is a good idea to null m before calling LongFoo. But I thought that GC can figure it out itself since m is a local var and should know that m is no longer referenced&lt;/p&gt;
&lt;p&gt;public void foo()&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; // allocate large memory&lt;/p&gt;
&lt;p&gt; &amp;nbsp; HughMem m &amp;nbsp;= new HughMem();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; ...&lt;/p&gt;
&lt;p&gt; &amp;nbsp; ...&lt;/p&gt;
&lt;p&gt; &amp;nbsp; // do a long process and GC got trigger here&lt;/p&gt;
&lt;p&gt; &amp;nbsp; LongFoo();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; // m is referenced anymore&lt;/p&gt;
&lt;p&gt; &amp;nbsp; ...&lt;/p&gt;
&lt;p&gt; &amp;nbsp; ...&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2345546" width="1" height="1"&gt;</description></item><item><title>re: He’s live… he’s live not… he’s live…</title><link>http://blogs.msdn.com/b/maoni/archive/2007/03/20/he-s-live-he-s-live-not-he-s-live.aspx#2297898</link><pubDate>Fri, 27 Apr 2007 12:56:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2297898</guid><dc:creator>dal</dc:creator><description>&lt;p&gt;Maoni, I thought I did understand.&lt;/p&gt;
&lt;p&gt;I understand that currently the JIT may cache a non-volatile value in a register and not need to read it again. In this case the JIT no longer needs to have access to the underlying object from which it obtained the value, so the object does not explicitly need to be &amp;quot;live&amp;quot;. &lt;/p&gt;
&lt;p&gt;However, this is up to the JIT - it could report the object alive until after the line of code that explicitly references the object, even if the JIT does not need the object in order to determine the value of the cached item. In other words, the determination of object lifetime is up to the JIT. &lt;/p&gt;
&lt;p&gt;IMO it ought to report the object alive until the last explicit reference to the object.&lt;/p&gt;
&lt;p&gt;If the JIT does not report the object as live until after the last explicit reference then it makes it nearly impossible to reason about object lifetime, as developers and reviewers will need to know both the documented rules of object lifetime in .NET and the undocumented caching behavior as implemented in the JIT. This could be version sensitive, and certainly varies with debug versus release builds.&lt;/p&gt;
&lt;p&gt;All the information I've read on object lifetime always discussed when the last reference to &amp;quot;this&amp;quot; occurred. The concern has been about when the last piece of data was extracted from &amp;quot;this&amp;quot; so that &amp;quot;this&amp;quot; was no longer needed. Adding caching behavior to this seems new to me.&lt;/p&gt;
&lt;p&gt;I only use volatile when multiple threads may access a field for reading/writing and the variable is not protected by a lock statement; this is part of reasoning about thread safety. If I understand you correctly, this may also affect object lifetime, as a side-effect of the JIT being unable to cache the value ina a volatile field.&lt;/p&gt;
&lt;p&gt;Please instruct me where my understanding is incomplete. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Thanks.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2297898" width="1" height="1"&gt;</description></item><item><title>re: He’s live… he’s live not… he’s live…</title><link>http://blogs.msdn.com/b/maoni/archive/2007/03/20/he-s-live-he-s-live-not-he-s-live.aspx#2190196</link><pubDate>Thu, 19 Apr 2007 13:52:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2190196</guid><dc:creator>Maoni</dc:creator><description>&lt;p&gt;dal, you misunderstood. I said if m_handle is not volatile then JIT could cache the value in the register so it will not need to read it again. So the object doesn't need to be live.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2190196" width="1" height="1"&gt;</description></item><item><title>re: He’s live… he’s live not… he’s live…</title><link>http://blogs.msdn.com/b/maoni/archive/2007/03/20/he-s-live-he-s-live-not-he-s-live.aspx#2025152</link><pubDate>Wed, 04 Apr 2007 14:45:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2025152</guid><dc:creator>dal</dc:creator><description>&lt;p&gt;Interesting. Couple of questions/observations...&lt;/p&gt;
&lt;p&gt;This is nitpicking, but...&lt;/p&gt;
&lt;p&gt;In the getter for property Target, &lt;/p&gt;
&lt;p&gt; if (IntPtr.Zero == h)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;return false;&lt;/p&gt;
&lt;p&gt;should probably be&lt;/p&gt;
&lt;p&gt; if (IntPtr.Zero == h)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;return null;&lt;/p&gt;
&lt;p&gt;Also, you state that if m_handle is not volatile then the jit could generate some code that caches the value of m_handle in a register, thereby subjecting it to garbage collection; thus, you simply cannot refer to m_handle after the call to Thread.VolatileRead to ensure that the &amp;quot;this&amp;quot; is kept alive till after that statement. &lt;/p&gt;
&lt;p&gt;This may be something that we must do but I question whether we should need to do so. This requires us to have very intimate knowledge about a part of the runtime (optimizations that JIT performs) that ought to be opaque. This makes it very difficult to reason about the correctness of the code. If inspection of the code makes it appear that a reference to &amp;quot;this&amp;quot; follows a method call, then the JIT should respect that and ensure that the object is kept alive till after that LOC executes. In other words, if the JIT wants to optimize and cache values in registers, it should also insert the equivalent of logical calls to KeepAlive(this) on our behalf. We would not then need to use the volatile modifier on instance members.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2025152" width="1" height="1"&gt;</description></item></channel></rss>