<?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>Fabulous Adventures In Coding : Memory Management</title><link>http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx</link><description>Tags: Memory Management</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Absence of evidence is not evidence of absence</title><link>http://blogs.msdn.com/ericlippert/archive/2009/10/12/absence-of-evidence-is-not-evidence-of-absence.aspx</link><pubDate>Mon, 12 Oct 2009 13:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9905526</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9905526.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9905526</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Today, two more subtly incorrect myths about C#.&lt;/P&gt;
&lt;P&gt;As you probably know, C# requires all local variables to be explicitly assigned before they are read, but assumes that all class instance field variables are initially assigned to default values. An explanation of why that is that I sometimes hear is "&lt;EM&gt;the compiler can easily prove that a local variable is not assigned, but it is much harder to prove that an instance&amp;nbsp;field is not assigned. And since the class's default constructor automatically assigns all instance fields to default values, you don't need to do the analysis for fields."&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Both statements are subtly incorrect.&lt;/P&gt;
&lt;P&gt;The first statement is incorrect because the compiler in fact cannot and does not prove that a local variable is not assigned. Proving that is (1) impossible, and (2) does not give us any useful information we can act upon. It's impossible because proving that a given variable is assigned a value is equivalent to solving the Halting Problem:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int x;&lt;BR&gt;if (/*condition requiring solution of the halting problem here*/) x = 10;&lt;BR&gt;print(x);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;If what we wanted to do was prove that x was &lt;EM&gt;unassigned&lt;/EM&gt; then we would have to &lt;EM&gt;at compile time&lt;/EM&gt; prove that the condition was false.&amp;nbsp;Our compiler is not that sophisticated! &lt;/P&gt;
&lt;P&gt;But the deeper point here is that we're not interested in proving for certain that x is &lt;EM&gt;unassigned&lt;/EM&gt;. We're interested in proving for certain that x is &lt;EM&gt;assigned&lt;/EM&gt;! If we can prove that for certain, then x is "definitely assigned". If we cannot prove that for certain then x is "not definitely assigned". We're only interested in "definitely unassigned" insofar as "definitely unassigned" is a stronger version of "not definitely assigned". If x is read from when it is "not definitely assigned", that's a bug. &lt;/P&gt;
&lt;P&gt;That is, we're attempting to prove that x is assigned, and our failure to prove that at every point where it is read is what motivates the error. That failure could be because of a bona fide bug in your program, or it could be because our flow analyzer is extremely conservative. For example:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int x, y = 0;&lt;BR&gt;if (0 * y == 0) x = 10;&lt;BR&gt;print(x);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;You and I know that x is definitely assigned, but in C# 3 the compiler is &lt;EM&gt;deliberately&lt;/EM&gt; not smart enough to prove that. (Interestingly enough, it &lt;EM&gt;was&lt;/EM&gt; smart&amp;nbsp;enough in C# 2. &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx"&gt;I broke that to bring the compiler into line with&amp;nbsp;the spec; being smarter but in violation of the spec is not necessarily a good thing&lt;/A&gt;.)&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This example again shows that we do not prove that x is unassigned; if we did prove that, then clearly our prover would contain an error, since you and I both know that x is definitely assigned. Rather, we fail to prove that x is assigned.&lt;/P&gt;
&lt;P&gt;This is an interesting twist on&amp;nbsp;the believers vs skeptics argument that goes like this: the skeptic says "there's no reliable evidence that bigfoot exists, therefore, bigfoot does not exist". The believer says&amp;nbsp;"absence of reliable evidence is not itself evidence of absence; and yes, bigfoot&amp;nbsp;does exist". In both cases, reasoning from a position of lacking reliable evidence is seldom good reasoning! But in our case, it is precisely &lt;EM&gt;because&lt;/EM&gt; we lack reliable evidence that we are coming to the conclusion that we do not know enough to allow you to read from x.&lt;/P&gt;
&lt;P&gt;(The relevant principle for tentatively concluding that bigfoot is mythical based on a lack of reliable evidence&amp;nbsp;is "extraordinary claims require extraordinary evidence". &lt;EM&gt;It&lt;/EM&gt; &lt;EM&gt;is reasonable to assume that&amp;nbsp;an extraordinary claim is false until reliable evidence is produced&lt;/EM&gt;.&amp;nbsp;When overwhelmingly reliable evidence is produced of an extraordinary claim -- say, the extraordinary claim that&amp;nbsp;time itself slows down when you move faster -- then it makes sense to believe the extraordinary claim. Overwhelming evidence has been provided for the theory of relativity, but not for the theory of bigfoot.)&lt;/P&gt;
&lt;P&gt;The second myth is that the default constructor of a class&amp;nbsp;initializes the fields to their default values. This can be shown to be false by several arguments. &lt;/P&gt;
&lt;P&gt;First, a class need not have a default constructor, and yet its fields are always observed to be initially assigned. If there is no default constructor, then something else must be initializing the fields. &lt;/P&gt;
&lt;P&gt;Second, even if a class does have a default constructor, there's no guarantee that it will be called. Some other constructor could be called.&lt;/P&gt;
&lt;P&gt;Third, the field initializers of a class run before any constructor body runs, therefore it cannot be the constructor body that does the initialization; that would be wiping out the results of the field initializers. &lt;/P&gt;
&lt;P&gt;Fourth, constructors can call other constructors; if each of those constructors was initializing the fields to zero, then that would be wasteful; we'd be unneccessarily re-initializing already-wiped-out fields. &lt;/P&gt;
&lt;P&gt;What actually happens is that the CLI memory allocator guarantees that the memory allocated for a given class instance will be initialized to all zeros before the constructor is called. By the time the constructors run the object is already freshly zeroed out&amp;nbsp;and ready to go.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9905526" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Science/default.aspx">Science</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx">myths</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/relativity/default.aspx">relativity</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/skepticism/default.aspx">skepticism</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/definite+assignment/default.aspx">definite assignment</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/constructors/default.aspx">constructors</category></item><item><title>Iterator Blocks, Part Six: Why no unsafe code?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/27/iterator-blocks-part-six-why-no-unsafe-code.aspx</link><pubDate>Mon, 27 Jul 2009 17:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9805754</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9805754.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9805754</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;There are three good reasons to disallow unsafe blocks inside an iterator block.&lt;/P&gt;
&lt;P&gt;First, it is an incredibly unlikely scenario. The purpose of iterator blocks is to make it easy to write an&amp;nbsp;iterator that walks over some abstract data type. This is highly likely to be fully managed code; it's simply not a by-design scenario. &lt;/P&gt;
&lt;P&gt;Second, the scenario is a violent mixing of "levels." You think of the level of abstraction of a programming language&amp;nbsp;feature as how "far from the machine" the feature is. Unsafe&amp;nbsp;pointer manipulation is as close to the machine as it gets in C#. You are running without a safety net, poking and peeking at the raw bytes&amp;nbsp;in the&amp;nbsp;virtual memory space of the process. All the protections of&amp;nbsp;verifiable type safety are completely gone and you have total responsibility over every&amp;nbsp;bit in the user-mode address space.&lt;/P&gt;
&lt;P&gt;Iterator blocks, by contrast, are the highest level of abstraction in C# 2.0. There is no immediately obvious mapping from&amp;nbsp;the source code to the generated code; it's a magic box that does the right thing because the compiler is doing&amp;nbsp;some pretty massive transformations on the code, generating&amp;nbsp;classes and implementing interfaces for you. &lt;/P&gt;
&lt;P&gt;Mixing those two levels of abstraction in one method seems like a really bad idea.&lt;/P&gt;
&lt;P&gt;Third, we would have to do some extra work to make "fixed" blocks work correctly, work that would be directly opposed to our guidelines for the correct and efficient use of the "fixed" block. &lt;/P&gt;
&lt;P&gt;I suppose I should briefly explain what the "fixed" block does. When you call unmanaged code that needs to, say, write into the unmanaged address that is the beginning of an array of 16 bit chars, somehow you need to tell the garbage collector&amp;nbsp;"hey, you, GC, running on that other thread over there -- if you get the urge to reorganize memory to be more efficient, I need you to please not move this array for a moment, because unmanaged code on this thread is going to be writing into that address". This operation is called "fixing" or "pinning" the object. &lt;/P&gt;
&lt;P&gt;Clearly it is a bad idea to pin lots of stuff and leave it pinned for a long time. The GC works as well as it does because it is able to reorganize memory to be more efficient; pinning blocks of memory across collections impedes the GC's ability to get work done. We therefore recommend that you pin as little as possible for as little time as possible.&lt;/P&gt;
&lt;P&gt;The CLR provides us two ways to pin something. The hard, flexible, expensive way is to explicitly get a GCHandle on the object, tell the garbage collector "this object is pinned", take the address of the object, do what you need to do, and then unpin it. &lt;/P&gt;
&lt;P&gt;The easy way is to mark a local variable as a "pinned local" using the "fixed" statement. The C# compiler will generate special code that marks the local as "pinned". When the garbage collector does a collection, clearly the GC needs to look at all the locals on the current stack frame, because those locals are all "alive". When the GC sees that a local is pinned, it not only notes that it is alive, it also makes a note to itself that the&amp;nbsp;referent of the contents&amp;nbsp;of this variable are not to be moved during the collection. This is a cheap and easy alternative to explicitly getting a GC handle, but it depends on the variable in question being a local. &lt;/P&gt;
&lt;P&gt;In an iterator block, locals are all realized by hoisting them to&amp;nbsp;fields. Because we cannot pin fields, we'd have to change the code generation for the fixed block so that it took out a handle to the object, pinned it, and ensured that the object was unpinned at some point.&lt;/P&gt;
&lt;P&gt;That's bad enough; now consider what happens when you yield while an object is pinned. Arbitrarily much time could pass between the yield and the unpin! This directly violates our guidance that things should be pinned for as little time as possible.&lt;/P&gt;
&lt;P&gt;For all those reasons, no unsafe code is allowed in iterator blocks. In the unlikely event that you need to dereference pointers in an iterator block, you can always extract the unsafe code to its own helper method and call it from the iterator block.&lt;/P&gt;
&lt;P&gt;***********&lt;/P&gt;
&lt;P&gt;I hope you've enjoyed this little trip into the weird corner cases of iterator blocks. This is a complicated feature with lots of interesting design choice points. &lt;/P&gt;
&lt;P&gt;I'm flying south to Canada to spend some time with my family on the beaver-shark infested shores of the great inland sea known as Lake Huron, so the next few fabulous adventures will be pre-recorded. See you when I'm back.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9805754" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Iterators/default.aspx">Iterators</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/unsafe+code/default.aspx">unsafe code</category></item><item><title>Iterator Blocks, Part Two: Why no ref or out parameters?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/13/iterator-blocks-part-two-why-no-ref-or-out-parameters.aspx</link><pubDate>Mon, 13 Jul 2009 16:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9776669</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9776669.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9776669</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;A long and detailed discussion of how exactly we implement iterator blocks would take me quite a while, and would duplicate work that has been done well by others already. I encourage you to start with Raymond’s series, which is a pretty gentle introduction: &lt;A href="http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519.aspx" mce_href="http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519.aspx"&gt;part 1&lt;/A&gt;, &lt;A href="http://blogs.msdn.com/oldnewthing/archive/2008/08/13/8854601.aspx" mce_href="http://blogs.msdn.com/oldnewthing/archive/2008/08/13/8854601.aspx"&gt;part 2&lt;/A&gt;, &lt;A href="http://blogs.msdn.com/oldnewthing/archive/2008/08/14/8862242.aspx" mce_href="http://blogs.msdn.com/oldnewthing/archive/2008/08/14/8862242.aspx"&gt;part 3&lt;/A&gt;. If you want a more detailed look at how this particular sausage is made, &lt;A href="http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx" mce_href="http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx"&gt;Jon’s article is quite in-depth&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;To make a long story short, we implement iterators by:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Spitting a class that implements the relevant interfaces. 
&lt;LI&gt;Hoisting locals of the iterator block to become fields of the class. 
&lt;LI&gt;Rewriting the iterator block as the “MoveNext” method of the class. 
&lt;LI&gt;Tracking the point where the last yield happened in the MoveNext method, and branching to that point directly using a switched “goto” when MoveNext is called. 
&lt;LI&gt;Moving the logic in “finally” blocks (or equivalents, like the auto-generated finally blocks associated with lock statements and using statements) into the Dispose method, to ensure that stuff gets cleaned up when the iteration is completed or abandoned.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This is not the only implementation strategy we could have pursued. As I said last time, we could have implemented full-blown continuations and built the whole thing out of them; any conceivable control flow can be built out of continuations. But getting continuations right requires a lot of support from the framework, and would be very expensive. We can get by with less, so we do.&lt;/P&gt;
&lt;P&gt;Similarly, we could have built this out of “coroutine &lt;A href="http://en.wikipedia.org/wiki/Fiber_(computer_science)" mce_href="http://en.wikipedia.org/wiki/Fiber_(computer_science)"&gt;fibers&lt;/A&gt;”. A fiber is like a thread in that it has its own stack, but the code on the fiber itself decides when the fiber is done running. Again, this is a strategy – implement coroutines – that I mentioned last time which we rejected as too costly and difficult to get right in the CLR. Again, we can get by with less, so we do.&lt;/P&gt;
&lt;P&gt;But this choice of a feasible, cost-effective implementation strategy then drives restrictions back into the design space; we have to lose some generality in order to make this strategy work.&lt;/P&gt;
&lt;P&gt;The first thing that we lose is the ability to have iterator blocks be in methods which take ref or out parameters. In order to preserve the values of local variables and formal parameters across calls to MoveNext, we hoist the locals and parameters into fields of a compiler-generated class. &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx"&gt;As I discussed earlier, the CLR designers had an implementation goal of being able to take advantage of the performance characteristics of the system stack.&lt;/A&gt; What happens when you store a reference in a field? The reference could be to something on the stack, but the field could live longer than the thing on the stack. The designers of the CLR were faced with four choices:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Build a system which is as fragile and horrid as unmanaged C code, a language in which accidentally storing a reference to something with too-short lifetime is a frequent source of awful crashing bugs and data corruptions. 
&lt;LI&gt;Disallow (*) taking references to locals; any local taken as a reference must be hoisted to become a field on a garbage-collected reference type. Safe, but slow. 
&lt;LI&gt;Disallow storing references in fields.&lt;/LI&gt;
&lt;LI&gt;Invent something else that solves this problem.&lt;BR&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The CLR designers chose the third option. Which means that our choice of hoisting parameters to fields immediately runs into a problem; we have no safe way of storing references to other variables in a field. The reference could be to something on the stack, but the iterator could live longer than the variable that is on the stack. A confluence of implementation choices has now driven an unfortunate and seemingly arbitrary restriction into the design. We lose a bit of generality in order to gain simplicity of implementation and higher performance in common cases.&lt;/P&gt;
&lt;P&gt;Now think about that decision from the perspective of the larger goal of the feature. Remember, the feature is not “make any possible method into an iterator block”. The feature is “make it easier to write code that enumerates the members of a collection”. An “out” or “ref” parameter exists solely to enable a method to mutate an outside variable and therefore pass back information to the caller when the method terminates. &lt;/P&gt;
&lt;P&gt;Why would you want to do that in a method whose sole purpose is to produce the sequence of values stored in a collection? What would the meaning of mutations to the variable even be if the iterator block mutates the variable multiple times as the iterator is running? Normally that kind of thing is not visible (modulo goofy multithreading scenarios) until the method is done, but an iterator block returns control to its caller many times before its done. &lt;/P&gt;
&lt;P&gt;This seems like a scenario which is uncommon, strange and hard to implement. And furthermore, there are ways to achieve mutation of outer variables during iteration without passing in a ref to a variable; you could pass in an Action delegate. Instead of this illegal program:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;IEnumerable&amp;lt;int&amp;gt; Frob(out string s)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; yield return 1;&lt;BR&gt;&amp;nbsp; s = "goodbye";&lt;BR&gt;}&lt;BR&gt;void Grob()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; string s = "hello";&lt;BR&gt;&amp;nbsp; foreach(int i in Frob(out s)) … &lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;you can always do the equivalent thing with this legal program:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;IEnumerable&amp;lt;int&amp;gt; Frob(Action&amp;lt;string&amp;gt; setter)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; yield return 1;&lt;BR&gt;&amp;nbsp; setter("goodbye");&lt;BR&gt;}&lt;BR&gt;void Grob()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; string s = "hello";&lt;BR&gt;&amp;nbsp; foreach(int i in Frob(x=&amp;gt;{s=x;})) … &lt;BR&gt;} &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Since making the more general feature work given our implementation constraints is (1) hard or impossible, (2) clearly a corner case, not a mainline scenario, and (3) has a possible workaround, it’s a no-brainer to put a restriction on the design and disallow ref and out parameters.&lt;/P&gt;
&lt;P&gt;Next time, why no yield in a finally block?&lt;/P&gt;
&lt;P&gt;***********&lt;/P&gt;
&lt;P&gt;(*) Or, weaker, make it allowed but unverifiable. That is pretty much the same thing from the compiler implementers perspective; we try to never generate unverifiable code unless it is specifically marked “unsafe”.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9776669" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Iterators/default.aspx">Iterators</category></item><item><title>The void is invariant</title><link>http://blogs.msdn.com/ericlippert/archive/2009/06/29/the-void-is-invariant.aspx</link><pubDate>Mon, 29 Jun 2009 17:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9756024</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>19</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9756024.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9756024</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;[UPDATES below]&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A while back I described &lt;A href="http://blogs.msdn.com/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx"&gt;a kind of variance that we’ve supported since C# 2.0.&lt;/A&gt; When assigning a method group to a delegate type, such that both the selected method and the delegate target agree that their return type is a reference type, then the conversion is allowed to be covariant. That is, you can say:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Giraffe GetGiraffe() { … }&lt;BR&gt;…&lt;BR&gt;Func&amp;lt;Animal&amp;gt; f = GetGiraffe;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This works logically because anyone who calls f must be able to handle any animal that comes back. The actual method claims to only return animals, and in fact, makes the stronger claim to only return giraffes. &lt;/P&gt;
&lt;P&gt;This works out in the CLR because the bits that make up a reference to an instance of Giraffe are exactly the same bits that make up a reference to that Giraffe interpreted as an instance of Animal. We can allow this magical conversion to happen because the CLR guarantees that it will all just work out without going in there and having to futz around with the bits.&lt;/P&gt;
&lt;P&gt;This is why this trick only works with reference types. A method that returns, say, a double cannot be converted via a covariant conversion to a delegate type that expects the method to return an object. Somewhere there would have to be code emitted that takes the returned double and boxes it to object; the bits of a double and the bits of a reference to an object boxing a double are completely different.&lt;/P&gt;
&lt;P&gt;But why doesn’t this trick work with void types? Here we have a method that returns some sort of success or failure code. Maybe we don’t care what it returns.&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static bool DoSomething(bool b)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; if (b) return DoTheThing();&lt;BR&gt;&amp;nbsp; else return DoTheOtherThing();&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Action&amp;lt;bool&amp;gt; action = DoSomething;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This doesn’t work. Why not? The caller of the action is not even going to &lt;EM&gt;use&lt;/EM&gt; the returned value, so it doesn’t matter one bit what it is! Shouldn’t “void” be considered &lt;EM&gt;a supertype of all possible types&lt;/EM&gt; for the purposes of covariant return type conversions from method groups to delegate types?&lt;/P&gt;
&lt;P&gt;No, and I’ll tell you why.&lt;/P&gt;
&lt;P&gt;Consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;bool x = DoSomething(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We spit out IL that does the following:&lt;/P&gt;
&lt;P&gt;(1) put true on the IL stack – the stack gets one deeper&lt;BR&gt;(2) call DoSomething – the argument is removed from the stack and the return value is placed on the stack.&amp;nbsp; Net, the stack stays the same size as before&lt;BR&gt;(3) stuff whatever on top of the stack into local variable x – the stack now returns to its original depth.&lt;/P&gt;
&lt;P&gt;Now consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;DoSomething(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We spit out IL that does the first two steps as before. But we cannot stop there! There is now a bool on the IL stack which needs to be removed. We generate a pop instruction to represent the fact that the returned bool has been discarded.&lt;/P&gt;
&lt;P&gt;Now consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;action(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;The compiler believes that action is a void-returning method, so it does not generate a pop instruction. If we allowed you to stuff DoSomething into the action, then we would be allowing you to misalign the IL stack!&lt;/P&gt;
&lt;P&gt;But didn’t I say “&lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx"&gt;the stack is an implementation detail?&lt;/A&gt;” Yes, but &lt;EM&gt;that’s a different stack&lt;/EM&gt;. The CLI specification describes a “virtual machine” which passes around arguments and returned values on a stack. An implementation of the CLI is required to make something that behaves like the specified machine, but it is not required to do so in any particular manner. It is not required to use the million-bytes-per-thread stack supplied to each thread by the operating system as its implementation of the IL stack; that’s a convenient structure to use, of course, but it’s an implementation detail that it does so.&lt;/P&gt;
&lt;P&gt;(As an aside: when we implemented the script engines, we also first specified our own private stack-based virtual machine. When we implemented it, we decided to put the information about “return addresses” – that is, “what code do I run next?” on the system stack, but we put arguments and return values of script functions in a stack-shaped block of memory that we allocated on our own. This made building the JScript garbage collector easier.)&lt;/P&gt;
&lt;P&gt;In practice, the jitter uses the system stack for some things and registers for other things. Return values are actually often sent back in a register, not on the stack. But that implementation detail doesn’t help us out when deciding what the conversion rules are; we have to assume that the implementation can do no more than what the CLI specification says. Had the CLI specification said “the returned value of any function is passed back in a ‘virtual register’” rather than having it pushed onto the stack, then we could have made void-returning delegates compatible with functions that returned anything. You can always just ignore the value in the register. But that’s not what the CLI specified, so that’s not what we can do. &lt;/P&gt;
&lt;P&gt;[UPDATE]&lt;/P&gt;
&lt;P&gt;A number of people have asked in the comments why we do not simply generate a helper method that does what you want. That is, when you say&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Action&amp;lt;bool&amp;gt; action = DoSomething;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;realize that as&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static&amp;nbsp;void DoSomethingHelper(bool b)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; bool result = DoSomething(b); // result is ignored&lt;BR&gt;}&lt;BR&gt;...&lt;BR&gt;Action&amp;lt;bool&amp;gt; action = DoSomethingHelper;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We could do that. But where would you like the line to be drawn? Should you be able to assign a&amp;nbsp;reference to a method that returns an int to a Func&amp;lt;Nullable&amp;lt;int&amp;gt;&amp;gt;? We could spit a helper method that converts the int to a nullable int.&amp;nbsp;What about Func&amp;lt;double&amp;gt;? We could spit a helper method that converts the int to a double. What about Func&amp;lt;object&amp;gt;? We could spit a helper method that boxes the int, unexpectedly allocating memory off the heap every time you call it. What about a Func&amp;lt;Foo&amp;gt; where there is a user-defined implicit conversion from int to Foo?&lt;/P&gt;
&lt;P&gt;We could be spitting arbitrarily complex fixer-upper methods that would seamlessly "do what you meant to say", and we have to stop somewhere.&amp;nbsp;The exact semantics of what we&amp;nbsp;do and do not&amp;nbsp;fix up would have to be designed, specified, implemented, tested, documented, shipped to customers and maintained forever. Those are costs. Plus, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx"&gt;every time we add a new conversion rule to the language we add breaking changes&lt;/A&gt;. The costs of those breaking changes to our customers have to be factored in.&lt;/P&gt;
&lt;P&gt;But more fundamentally, one of the design principles of C# is "if &lt;STRONG&gt;you say something wrong then &lt;EM&gt;we tell you&lt;/EM&gt; rather than trying &lt;EM&gt;to guess what you meant&lt;/EM&gt;&lt;/STRONG&gt;". JScript is deliberately a "muddle on through and do the best you can" language; C# is not. If what you want to do is make a delegate to a helper method then you express that intention by going right ahead and making that method.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9756024" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx">Conversions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category></item><item><title>“Out Of Memory” Does Not Refer to Physical Memory</title><link>http://blogs.msdn.com/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx</link><pubDate>Mon, 08 Jun 2009 17:04:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9628808</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>46</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9628808.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9628808</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/OutOfMemoryDoesNotRefertoPhysicalMemory_9674/ExtendedMemory_2.jpg"&gt;&lt;IMG title="Inside Eric's head" style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; DISPLAY: inline; MARGIN: 0px 15px 0px 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=192 alt="Inside Eric's head" src="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/OutOfMemoryDoesNotRefertoPhysicalMemory_9674/ExtendedMemory_thumb.jpg" width=192 align=left border=0&gt;&lt;/A&gt; I started programming on x86 machines during a period of large and rapid change in the memory management strategies enabled by the Intel processors. The pain of having to know the difference between “extended memory” and “expanded memory” has faded with time, fortunately, along with my memory of the exact difference. &lt;/P&gt;
&lt;P&gt;As a result of that early experience, I am occasionally surprised by the fact that many professional programmers seem to have ideas about memory management that haven’t been true since before the “80286 protected mode” days. &lt;/P&gt;
&lt;P&gt;For example, I occasionally get the question &lt;STRONG&gt;“I got an ‘out of memory’ error but I checked and the machine has plenty of RAM, what’s up with that?”&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;Imagine, thinking that the amount of memory you have in your machine is relevant when you run out of it! How charming! :-)&lt;/P&gt;
&lt;P&gt;The problem, I think, with most approaches to describing modern virtual memory management is that they start with assuming the DOS world – that “memory” equals RAM, aka “physical memory”, and that “virtual memory” is just a clever trick to make the physical memory &lt;EM&gt;seem&lt;/EM&gt; bigger. Though historically that is how virtual memory evolved on Windows, and is a reasonable approach, that’s not how I &lt;EM&gt;personally&lt;/EM&gt; conceptualize virtual memory management.&lt;/P&gt;
&lt;P&gt;So, a quick sketch of my somewhat backwards conceptualization of virtual memory. But first a caveat. The modern Windows memory management system is far more complex and interesting than this brief sketch, which is intended to give the flavour of virtual memory management systems in general and some mental tools for thinking clearly about what the relationship between storage and addressing is. &lt;STRONG&gt;It is not by any means a tutorial on the real memory manager.&lt;/STRONG&gt; (For more details on how it actually works, &lt;A href="http://msdn.microsoft.com/en-us/library/ms810616.aspx"&gt;try this MSDN article&lt;/A&gt;.)&lt;/P&gt;
&lt;P&gt;I’m going to start by assuming that you understand two concepts that need no additional explanation: the operating system manages &lt;STRONG&gt;processes&lt;/STRONG&gt;, and the operating system manages &lt;STRONG&gt;files on disk&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Each process can have as much data storage as it wants. It asks the operating system to create for it a certain amount of data storage, and the operating system does so. &lt;/P&gt;
&lt;P&gt;Now, already I am sure that myths and preconceptions are starting to crowd in. Surely the process cannot ask for “as much as it wants”. Surely the 32 bit process can only ask for 2 GB, tops. Or surely the 32 bit process can only ask for as much data storage as there is RAM. Neither of those assumptions are true. The &lt;STRONG&gt;amount of data storage reserved for a process is only limited by the amount of space that the operating system can get on the disk&lt;/STRONG&gt;. (*) &lt;/P&gt;
&lt;P&gt;This is the key point: the data storage that we call “process memory” is in my opinion best visualized as a &lt;STRONG&gt;massive file on disk&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;So, suppose the 32 bit process requires huge amounts of storage, and it asks for storage many times. Perhaps it requires a total of 5 GB of storage. The operating system finds enough disk space for 5GB in files and tells the process that sure, the storage is available. &lt;EM&gt;How does the process then write to that storage? &lt;/EM&gt;The process only has 32 bit pointers, but uniquely identifying every byte in 5GB worth of storage would require at least 33 bits.&lt;/P&gt;
&lt;P&gt;Solving that problem is where things start to get a bit tricky. &lt;/P&gt;
&lt;P&gt;The 5GB of storage is split up into chunks, typically 4KB each, called “pages”. The operating system gives the process a 4GB “virtual address space” – over a million pages - which &lt;EM&gt;can&lt;/EM&gt; be addressed by a 32 bit pointer. The process then tells the operating system which pages from the 5GB of on-disk storage should be “mapped” into the 32 bit address space. (How? Here’s a page where &lt;A href="http://blogs.msdn.com/oldnewthing/archive/2004/08/10/211890.aspx" mce_href="http://blogs.msdn.com/oldnewthing/archive/2004/08/10/211890.aspx"&gt;Raymond Chen gives an example of how to allocate a 4GB chunk and map a portion of it.&lt;/A&gt;)&lt;/P&gt;
&lt;P&gt;Once the mapping is done then the operating system knows that when the process #98 attempts to use pointer 0x12340000 in its address space, that this corresponds to, say, the byte at the beginning of page #2477, and the operating system knows where that page is stored on disk. When that pointer is read from or written to, the operating system can figure out what byte of the disk storage is referred to, and do the appropriate read or write operation.&lt;/P&gt;
&lt;P&gt;An “out of memory” error almost never happens because there’s not enough &lt;EM&gt;storage&lt;/EM&gt; available; as we’ve seen, storage is disk space, and disks are huge these days. Rather, an “out of memory” error happens because the process is unable to find a large enough section of &lt;EM&gt;contiguous unused pages in its virtual address space to do the requested mapping.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Half (&lt;A href="http://blogs.msdn.com/oldnewthing/archive/2004/08/22/218527.aspx" mce_href="http://blogs.msdn.com/oldnewthing/archive/2004/08/22/218527.aspx"&gt;or, in some cases, a quarter&lt;/A&gt;) of the 4GB address space is reserved for the operating system to store it’s process-specific data. Of the remaining “user” half of the address space, significant amounts of it are taken up by the EXE and DLL files that make up the application’s code. Even if there is enough space in total, there might not be an unmapped “hole” in the address space large enough to meet the process’s needs.&lt;/P&gt;
&lt;P&gt;The process can deal with this situation by attempting to identify portions of the virtual address space that no longer need to be mapped, “unmap” them, and then map them to some other pages in the storage file. If the 32 bit process is &lt;EM&gt;designed&lt;/EM&gt; to handle massive multi-GB data storages, obviously that’s what its &lt;EM&gt;got&lt;/EM&gt; to do. Typically such programs are doing video processing or some such thing, and can safely and easily re-map big chunks of the address space to some other part of the “memory file”.&lt;/P&gt;
&lt;P&gt;But what if it isn’t? What if the process is a much more normal, well-behaved process that just wants a few hundred million bytes of storage? If such a process is just ticking along normally, and it then tries to allocate some massive string, the operating system will almost certainly be able to provide the disk space. But how will the process map the massive string’s pages into address space? &lt;/P&gt;
&lt;P&gt;If by chance there isn’t enough contiguous address space then the process will be unable to obtain a pointer to that data, and it is effectively useless. In that case the process issues an “out of memory” error. Which is a misnomer, these days. It really should be an “unable to find enough contiguous address space” error; there’s plenty of &lt;EM&gt;memory&lt;/EM&gt; because memory equals disk space.&lt;/P&gt;
&lt;P&gt;I haven’t yet mentioned RAM. &lt;STRONG&gt;RAM can be seen as merely a performance optimization.&lt;/STRONG&gt; Accessing data in RAM, where the information is stored in electric fields that&amp;nbsp;propagate &lt;STRONG&gt;at close to the speed of light&lt;/STRONG&gt; is &lt;EM&gt;much&lt;/EM&gt; faster than accessing data on disk, where information is stored in enormous, heavy ferrous metal molecules that move at &lt;STRONG&gt;close to the speed of my Miata&lt;/STRONG&gt;. (**)&lt;/P&gt;
&lt;P&gt;The operating system keeps track of what pages of storage from which processes are being accessed most frequently, and makes a &lt;EM&gt;copy&lt;/EM&gt; of them in RAM, to get the speed increase. When a process accesses a pointer corresponding to a page that is not currently cached in RAM, the operating system does a “page fault”, goes out to the disk, and makes a copy of the page from disk to RAM, making the reasonable assumption that it’s about to be accessed again some time soon.&lt;/P&gt;
&lt;P&gt;The operating system is also very smart about sharing read-only resources. If two processes both load the same page of code from the same DLL, then the operating system can share the RAM cache between the two processes. Since the code is presumably not going to be changed by either process, it's perfectly sensible to save the duplicate page of RAM by sharing it.&lt;/P&gt;
&lt;P&gt;But even with clever sharing, eventually this caching system is going to run out of RAM. When that happens, the operating system makes a guess about which pages are &lt;EM&gt;least&lt;/EM&gt; likely to be accessed again soon, writes them out to disk if they’ve changed, and frees up that RAM to read in something that is more likely to be accessed again soon.&lt;/P&gt;
&lt;P&gt;When the operating system guesses incorrectly, or, more likely, when there simply is not enough RAM to store all the frequently-accessed pages in all the running processes, then the machine starts “thrashing”. The operating system spends all of its time writing and reading the expensive disk storage, the disk runs constantly, and you don’t get any work done.&lt;/P&gt;
&lt;P&gt;This also&amp;nbsp;means that "running out of RAM" seldom(***) results in an “out of memory” error. Instead of an error, it results in bad performance because the full cost of the fact that storage is actually on disk suddenly becomes relevant.&lt;/P&gt;
&lt;P&gt;Another way of looking at this is&amp;nbsp;that &lt;STRONG&gt;the total amount of virtual memory your program consumes is really not hugely relevant to its performance&lt;/STRONG&gt;. What is relevant is not the total amount of virtual memory consumed, but rather, (1) how much of that memory is not shared with other processes, (2) how big&amp;nbsp;the "working set" of commonly-used pages is, and (3) whether the working sets of all active processes are larger than available RAM.&lt;/P&gt;
&lt;P&gt;By now it should be clear why “out of memory” errors usually have nothing to do with how much &lt;EM&gt;physical&lt;/EM&gt; memory you have, or how even how much &lt;EM&gt;storage&lt;/EM&gt; is available. It’s almost always about the &lt;EM&gt;address space&lt;/EM&gt;, which on 32 bit Windows is relatively small and easily fragmented. &lt;/P&gt;
&lt;P&gt;And of course, many of these problems effectively go away on 64 bit Windows, where the address space is billions of times larger and therefore much harder to fragment. (The problem of thrashing of course still occurs if physical memory is smaller than total working set, no matter how big the address space gets.)&lt;/P&gt;
&lt;P&gt;This way of conceptualizing virtual memory is completely backwards from how it is usually conceived. Usually it’s conceived as storage being &lt;STRONG&gt;a chunk of physical memory&lt;/STRONG&gt;, and that the &lt;STRONG&gt;contents of physical memory are swapped out to disk when physical memory gets too full&lt;/STRONG&gt;. But I much prefer to think of storage as being &lt;STRONG&gt;a chunk of disk storage&lt;/STRONG&gt;, and physical memory being &lt;STRONG&gt;a smart caching mechanism that makes the disk look faster&lt;/STRONG&gt;. Maybe I’m crazy, but that helps me understand it better.&lt;/P&gt;
&lt;P&gt;************* &lt;/P&gt;
&lt;P&gt;(*) OK, I lied. 32 bit Windows limits the total amount of process storage on disk to 16 TB, and 64 bit Windows limits it to 256 TB. But there is no reason why a single process could not allocate multiple GB of that if there’s enough disk space.&lt;/P&gt;
&lt;P&gt;(**) Numerous electrical engineers pointed out to me that of course the individual&amp;nbsp;&lt;EM&gt;electrons&lt;/EM&gt; do not move fast at all; it's the &lt;EM&gt;field&lt;/EM&gt; that moves so fast. I've updated the text; I hope you're all happy with it now.&lt;/P&gt;
&lt;P&gt;(***) It is possible in some virtual memory systems to mark a page as “the performance of this page is so crucial that it must always remain in RAM”. If there are more such pages than there are pages of RAM available, then you could get an “out of memory” error from not having enough RAM. But this is a much more rare occurrence than running out of address space.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9628808" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category></item><item><title>The Stack Is An Implementation Detail, Part Two</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx</link><pubDate>Mon, 04 May 2009 20:57:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9586162</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>20</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9586162.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9586162</wfw:commentRss><description>&lt;div class="mine"&gt; &lt;p&gt;A number of people have asked me, in the wake of my earlier posting about value types being on the stack, &lt;em&gt;why&lt;/em&gt; it is that value types go on the stack but reference types do not.&lt;/p&gt; &lt;p&gt;The short answer is “because they can”. And since the stack is &lt;em&gt;cheap&lt;/em&gt;, we &lt;em&gt;do&lt;/em&gt; put them on the stack when possible.&lt;/p&gt; &lt;p&gt;The long answer is… long.&lt;/p&gt; &lt;p&gt;I’ll need to give a high-level description of the memory management strategies that we call “stack” and “heap”. Heap first.&lt;/p&gt; &lt;p&gt;The CLRs garbage-collected heap is a marvel of engineering with a huge amount of detail; this sketch is not actually how it works, but it’s a good enough approximation to get the idea. &lt;/p&gt; &lt;p&gt;The idea is that there is a large block of memory reserved for instances of reference types. This block of memory can have “holes” – some of the memory is associated with “live” objects, and some of the memory is free for use by newly created objects. Ideally though we want to have all the allocated memory bunched together and a large section of “free” memory at the top.&lt;/p&gt; &lt;p&gt;If we’re in that situation when new memory is allocated then the “high water mark” is bumped up, eating up some of the previously “free” portion of the block. The newly-reserved memory is then usable for the reference type instance that has just been allocated. That is &lt;em&gt;extremely cheap&lt;/em&gt;; just a single pointer move, plus zeroing out the newly reserved memory if necessary.&lt;/p&gt; &lt;p&gt;If we have holes then we can maintain a “free list” – a linked list of holes. We can then search the free list for a hole of appropriate size and fill it in. This is a bit more expensive since there is a list search. We want to avoid this suboptimal situation if possible.&lt;/p&gt; &lt;p&gt;When a garbage collection is performed there are three phases: mark, sweep and compact. In the “mark” phase, we assume that everything in the heap is “dead”. The CLR knows what objects were “guaranteed alive” when the collection started, so those guys are marked as alive. Everything they refer to is marked as alive, and so on, until the transitive closure of live objects are all marked. In the “sweep” phase, all the dead objects are turned into holes. In the “compact” phase, the block is reorganized so that it is one contiguous block of live memory, free of holes.&lt;/p&gt; &lt;p&gt;This sketch is complicated by the fact that there are actually &lt;em&gt;three&lt;/em&gt; such arenas; the CLR collector is &lt;em&gt;generational&lt;/em&gt;. Objects start off in the “short lived” heap. If they survive they eventually move to the “medium lived” heap, and if they survive there long enough, they move to the “long lived” heap. The GC runs very often on the short lived heap and very seldom on the long lived heap; the idea is that we do not want to have the expense of constantly re-checking a long-lived object to see if it is still alive. But we also want short-lived objects to be reclaimed swiftly.&lt;/p&gt; &lt;p&gt;The GC has a huge amount of carefully tuned policy that ensures high performance; it attempts to balance the memory and time costs of having a Swiss-cheesed heap against the high cost of the compaction phase. Extremely large objects are stored in a special heap that has different compaction policy. And so on. I don’t know all the details, and fortunately, I don’t need to. (And of course, I have left out lots of additional complexity that is not germane to this article – pinning and finalization and weak refs and so on.)&lt;/p&gt; &lt;p&gt;Now compare this to the stack. The stack is like the heap in that it is a big block of memory with a “high water mark”. But what makes it a “stack” is that the memory on the bottom of the stack always lives longer than the memory on the top of the stack; the stack is strictly ordered. The objects that are going to die first are on the top, the objects that are going to die last are on the bottom. And with that guarantee, we know that the stack will never have holes, and therefore will not need compacting. We know that the stack memory will always be “freed” from the top, and therefore do not need a free list. We know that anything low-down on the stack is guaranteed alive, and so we do not need to mark or sweep.&lt;/p&gt; &lt;p&gt;On a stack, the allocation is just a single pointer move – the same as the best (and typical) case on the heap. But because of all those guarantees, the deallocation is also a single pointer move! And &lt;em&gt;that&lt;/em&gt; is where the huge time performance savings is. A lot of people seem to think that heap allocation is expensive and stack allocation is cheap. They are actually about the same, typically. It’s the deallocation costs – the marking and sweeping and compacting and moving memory from generation to generation – that are massive for heap memory compared to stack memory.&lt;/p&gt; &lt;p&gt;Clearly it is better to use a stack than a GC heap if you can. When can you? Only when you can guarantee that all the necessary conditional that make a stack work are actually achieved. Local variables and formal parameters of value type are the sweet spot that achieve that. The locals of frames on the bottom of the stack clearly live longer than the locals on the frames of the top of the stack. Locals of value type are copied by value, not by reference, so the local is the only thing that references the memory; there is no need to track who is referencing a particular value to determine its lifetime. And the only way to take a ref to a local is to pass it as a ref or out parameter, which just passes the ref on &lt;u&gt;up&lt;/u&gt; the stack. The local is going to be alive anyway, so the fact that there is a ref to it “higher up” the call stack doesn’t change its lifetime.&lt;/p&gt; &lt;p&gt;aside &lt;br&gt;{ &lt;/p&gt; &lt;p&gt;A few asides:&lt;/p&gt; &lt;p&gt;This explains why you cannot make a “ref int” field. If you could then you could &lt;em&gt;store&lt;/em&gt; a ref to the value of a short-lived local inside a long-lived object. Were that legal then using the stack as a memory management technique would no longer be a viable optimization; value types would be just another kind of reference type and would have to be garbage collected.&lt;/p&gt; &lt;p&gt;Anonymous function closures and iterator block closures are implemented behind-the-scenes by turning locals and formal parameters into fields. So now you know why it is illegal to capture a ref or out formal parameter in an anonymous function or iterator block; doing so would not be a legal field. &lt;/p&gt; &lt;p&gt;Of course we do not want to have ugly and bizarre rules in the language like “you can close over any local or value parameter &lt;em&gt;but not a ref or out parameter&lt;/em&gt;”. But because we want to be able to get the optimization of putting value types on the stack, we have chosen to put this odd restriction into the language. Design is, as always, the art of finding compromises. &lt;/p&gt; &lt;p&gt;Finally, the CLR &lt;em&gt;does&lt;/em&gt; allow “ref return types”; you could in theory have a method “ref int M() { … }” that returned a reference to an integer variable. If for some bizarre reason we ever decided to allow that in C#, we’d have to fix up the compiler and verifier so that they ensured that it was only possible to return refs to variables that were known to be on the heap, or known to be “lower down” on the stack than the callee.&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;So there you go. Local variables of value type go on the stack because they can. They can because (1) “normal” locals have strict ordering of lifetime, and (2) value types are always copied by value and (3) it is illegal to store a reference to a local anywhere that could live longer than the local. By contrast, reference types have a lifetime based on the number of living references, are copied by reference, and those references can be stored anywhere. &lt;strong&gt;The additional flexibility that reference types give you comes at the cost of a much more complex and expensive garbage collection strategy.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;But again, all of this is an implementation detail. Using the stack for locals of value type is just an optimization that the CLR performs on your behalf. The relevant feature of value types is &lt;strong&gt;that they have the semantics of being copied by value&lt;/strong&gt;, not that &lt;strong&gt;sometimes their deallocation can be optimized by the runtime&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9586162" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Value+Types/default.aspx">Value Types</category></item><item><title>The Stack Is An Implementation Detail, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx</link><pubDate>Mon, 27 Apr 2009 16:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9549311</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>35</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9549311.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9549311</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_4.jpg" mce_href="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_4.jpg"&gt;&lt;IMG title="Stack&lt;Stone&gt;" style="BORDER-TOP-WIDTH: 0px; DISPLAY: inline; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: 0px; MARGIN-RIGHT: 0px; BORDER-RIGHT-WIDTH: 0px" height=240 alt="Stack&lt;Stone&gt;" src="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_thumb_1.jpg" width=156 align=left border=0 mce_src="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_thumb_1.jpg"&gt;&lt;/A&gt;I blogged a while back about how &lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx"&gt;“references” are often described as “addresses”&lt;/A&gt; when describing the semantics of the C# memory model. Though that’s arguably &lt;EM&gt;correct&lt;/EM&gt;, it’s also arguably an &lt;EM&gt;implementation detail&lt;/EM&gt; rather than an important eternal truth. Another memory-model implementation detail I often see presented as a fact is “value types are allocated on the stack”. I often see it because of course, &lt;A href="http://msdn.microsoft.com/en-us/library/system.valuetype.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.valuetype.aspx"&gt;that’s what our documentation says&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;Almost every article I see that describes the difference between value types and reference types explains in (frequently incorrect) detail about what “the stack” is and how the major difference between value types and reference types is that value types go on the stack. I’m sure you can find dozens of examples by searching the web.&lt;/P&gt;
&lt;P&gt;I find this characterization of a value type based on its &lt;EM&gt;implementation details&lt;/EM&gt; rather than its &lt;EM&gt;observable characteristics&lt;/EM&gt; to be both confusing and unfortunate. Surely the most relevant fact about value types is not the implementation detail of &lt;EM&gt;how they are allocated&lt;/EM&gt;, but rather the &lt;EM&gt;by-design semantic meaning&lt;/EM&gt; of “value type”, namely &lt;EM&gt;that they are always copied “by value”&lt;/EM&gt;. If the relevant thing was their allocation details then we’d have called them “heap types” and “stack types”. But that’s not relevant most of the time. Most of the time the relevant thing is their copying and identity semantics.&lt;/P&gt;
&lt;P&gt;I regret that the documentation does not focus on what is most relevant; by focusing on a largely irrelevant implementation detail, we enlarge the importance of that implementation detail and obscure the importance of what makes a value type semantically useful. I dearly wish that all those articles explaining what “the stack” is would instead spend time explaining what exactly “copied by value” means and how misunderstanding or misusing “copy by value” can cause bugs.&lt;/P&gt;
&lt;P&gt;Of course, the simplistic statement I described is not even &lt;EM&gt;true&lt;/EM&gt;. As the MSDN documentation correctly notes, value types are allocated on the stack &lt;EM&gt;sometimes&lt;/EM&gt;. For example, the memory for an integer field in a class type is part of the class instance’s memory, which is allocated on the heap. A local variable is hoisted to be implemented as a field of a hidden class if the local is an outer variable used by an anonymous method(*) so again, the storage associated with that local variable will be on the heap if it is of value type.&lt;/P&gt;
&lt;P&gt;But more generally, again we have &lt;STRONG&gt;an explanation that doesn’t actually explain anything&lt;/STRONG&gt;. Leaving performance considerations aside, what possible difference does it make &lt;EM&gt;to the developer&lt;/EM&gt; whether the CLR’s jitter happens to allocate memory for a particular local variable by adding some integer to the pointer that we call “the stack pointer” or adding the same integer to the pointer that we call “the top of the GC heap”? As long as the implementation maintains the semantics guaranteed by the specification, it can choose any strategy it likes for generating efficient code. &lt;/P&gt;
&lt;P&gt;Heck, there’s no requirement that the &lt;EM&gt;operating system&lt;/EM&gt; that the CLI is implemented on top of provide a per-thread one-meg array called “the stack”. That Windows typically does so, and that this one-meg array is an efficient place to store small amounts of short-lived data is great, but it’s not a requirement that an operating system provide such a structure, or that the jitter use it. The jitter could choose to put every local “on the heap” and live with the performance cost of doing so, as long as the value type semantics were maintained.&lt;/P&gt;
&lt;P&gt;Even worse though is the frequently-seen characterization that value types are “small and fast” and reference types are “big and slow”. Indeed, value types that can be jitted to code that allocates off the stack are extremely fast to both allocate and deallocate. Large structures heap-allocated structures like arrays of value type are also pretty fast, particularly if you need them initialized to the default state of the value type. And there is some memory overhead to ref types. And there are some high-profile cases where value types give a big perf win. &lt;STRONG&gt;But in the vast majority of programs out there, local variable allocations and deallocations are not going to be the performance bottleneck.&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;Making the nano-optimization of making a type that really should be a ref type into a value type for a few nanoseconds of perf gain is probably not worth it. I would only be making that choice if profiling data showed that there was a large, real-world-customer-impacting performance problem directly mitigated by using value types. Absent such data, I’d always make the choice of value type vs reference type based on whether the type is &lt;EM&gt;semantically&lt;/EM&gt; representing a value or &lt;EM&gt;semantically&lt;/EM&gt; a reference to something.&lt;/P&gt;
&lt;P&gt;UPDATE: &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx"&gt;Part two is here&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;*******&lt;/P&gt;
&lt;P&gt;(*) Or in an iterator block.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9549311" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Value+Types/default.aspx">Value Types</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx">myths</category></item><item><title>References are not addresses</title><link>http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx</link><pubDate>Tue, 17 Feb 2009 21:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9428097</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>75</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9428097.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9428097</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;[NOTE: Based on some insightful comments I have updated this article to describe more clearly the relationships between references, pointers and addresses. Thanks to those who commented.]&lt;/P&gt;
&lt;P&gt;I review a fair number of C# books; in all of them of course the author attempts to explain the difference between reference types and value types. Unfortunately, most of them do so by saying something like "&lt;EM&gt;a variable of reference type &lt;STRONG&gt;stores the&lt;/STRONG&gt; &lt;STRONG&gt;address&lt;/STRONG&gt; of the object&lt;/EM&gt;". I always object to this. The last time this happened the author asked me for a more detailed explanation of why I always object, which I shall share with you now:&lt;/P&gt;
&lt;P&gt;We have the abstract concept of "a reference". If I were to write about "Beethoven's Ninth Symphony", those two-dozen characters are not a 90-minute long symphonic masterwork with a large choral section. They're a reference to that thing, not the thing itself. And this reference itself contains references -- the word "Beethoven" is not a long-dead famously deaf Romantic Period composer, but it is a reference to one.&lt;/P&gt;
&lt;P&gt;Similarly in programming languages we have the concept of "a reference" distinct from "the referent". 
&lt;P&gt;The inventor of the C programming language, oddly enough, chose to not have the concept of references at all. Rather, Ritchie chose to have "pointers" be first-class entities in the language. A pointer in C is like a reference in that it refers to some data by tracking&amp;nbsp;its location, but there are more smarts in a pointer; you can perform arithmetic on a pointer as if it were a number, you can take the difference between two pointers that are both in the interior of the same array and get a sensible result,&amp;nbsp;and so on. 
&lt;P&gt;Pointers are strictly "more powerful" than references; &lt;STRONG&gt;anything you can do with references you can do with pointers&lt;/STRONG&gt;, but not vice versa. I imagine that's why there are no references in C -- it's a deliberately austere and powerful language. 
&lt;P&gt;The down side of pointers-instead-of-references is that pointers are hard for many novices to understand, and make it very very very easy to shoot yourself in the foot. 
&lt;P&gt;Pointers are typically &lt;EM&gt;implemented&lt;/EM&gt; as &lt;STRONG&gt;addresses&lt;/STRONG&gt;. An address is a number which is an offset into the "array of bytes" that is the entire virtual address space of the process (or, sometimes, an offset into some well-known portion of that address space -- I'm thinking of "near" vs. "far" pointers in win16 programming. But for the purposes of this article let's assume that an address is a byte offset into the whole address space.) Since addresses are just numbers you can easily perform pointer arithmetic with them. 
&lt;P&gt;Now consider C#, a language which has &lt;STRONG&gt;both references and pointers&lt;/STRONG&gt;. There are some things you can only do with pointers, and we want to have a language that allows you to do those things (under carefully controlled conditions that call out that you are doing something that possibly breaks type safety, hence "unsafe".)&amp;nbsp; But we also do not want to force anyone to have to understand pointers in order to do programming with references. 
&lt;P&gt;We also want to avoid some of the optimization nightmares that languages with pointers have. Languages with heavy use of pointers have a hard time doing garbage collection, optimizations, and so on, because it is infeasible to guarantee that no one has an interior pointer to an object, and therefore the object must remain alive and immobile. 
&lt;P&gt;For all these reasons we do not describe references as addresses in the specification. The spec just says that a variable of reference type "stores a reference" to an object, and leaves it completely vague as to how that might be implemented. Similarly, a pointer variable stores "the address" of an object, which again, is left pretty vague. Nowhere do we say that references are the same as addresses. 
&lt;P&gt;So, in C# a reference is some vague thing that lets you reference an object. You cannot do anything with a reference except dereference it, and compare it with another reference for equality. And in C# a pointer is identified as an address. 
&lt;P&gt;By contrast with a reference, you can do much more with a&amp;nbsp;pointer that contains an address.&amp;nbsp;Addresses can be manipulated mathematically; you can subtract one from another, you can add integers to them, and so on. Their legal operations indicate that they are "fancy numbers" that index into the "array" that is the virtual address space of the process. 
&lt;P&gt;Now, behind the scenes, the CLR actually &lt;EM&gt;does&lt;/EM&gt; implement managed object references as addresses to objects owned by the garbage collector, but &lt;EM&gt;that is an implementation detail.&lt;/EM&gt; There's no reason why it has to do that other than efficiency and flexibility. &lt;STRONG&gt;C# references could be implemented by opaque handles that are meaningful only to the garbage collector&lt;/STRONG&gt;, which, frankly, is how I prefer to think of them. That the "handle" happens to actually be an address at runtime is an implementation detail which I should neither know about nor rely upon. (Which is the whole point of encapsulation; the client doesn't have to know.) 
&lt;P&gt;I therefore have three reasons why authors should not explain that "references are addresses". 
&lt;P&gt;1) &lt;STRONG&gt;It's close to a lie.&lt;/STRONG&gt; References cannot be &lt;EM&gt;treated&lt;/EM&gt; as addresses by the user, and in fact, they do not &lt;EM&gt;necessarily&lt;/EM&gt; contain an address in the implementation. (Though our implementation happens to do so.) 
&lt;P&gt;2) &lt;STRONG&gt;It's an explanation that explains nothing to novice programmers.&lt;/STRONG&gt; Novice programmers probably do not know that an "address" is an offset into the array of bytes that is all process memory. To understand what an "address" is with any kind of depth, the novice programmer &lt;EM&gt;already has to understand pointer types and addresses&lt;/EM&gt; -- basically, they have to understand the memory model of many implementations of C. This is one of those "it's clear only if it's already known" situations that are so common in books for beginners. 
&lt;P&gt;3) If these novices eventually learn about pointer types in C#, their confused understanding of references will probably make it &lt;STRONG&gt;harder, not easier&lt;/STRONG&gt;, to understand how pointers work in C#. The novice could sensibly reason "&lt;EM&gt;If a reference is an address and a pointer is an address, then I should be able to cast any reference to a pointer in unsafe code, right?&lt;/EM&gt;"&amp;nbsp; But you cannot. 
&lt;P&gt;If you think of a reference is actually being an opaque GC handle then it becomes clear that to find the address associated with the handle you have to somehow "fix" the object. You have to tell the GC "until further notice, the object with this handle must not be moved in memory, because someone might have an interior pointer to it". (There are various ways to do that which are beyond the scope of this screed.) 
&lt;P&gt;Basically what I'm getting at here is that &lt;STRONG&gt;an understanding of the&amp;nbsp;meaning of "addresses" in any language requires a moderately deep understanding of the memory model of that language&lt;/STRONG&gt;. If an author does not provide an explanation of the memory model of either C or C#, then explaining references in terms of addresses becomes an exercise in question begging. It raises more questions than it answers. 
&lt;P&gt;This is one of those situations where the author has the hard call of deciding whether an &lt;STRONG&gt;inaccurate oversimplification&lt;/STRONG&gt; serves the larger pedagogic goal better than an &lt;STRONG&gt;accurate digression&lt;/STRONG&gt; or a &lt;STRONG&gt;vague hand-wave&lt;/STRONG&gt;. 
&lt;P&gt;In the counterfactual world where I am writing a beginner C# book, I would personally opt for the vague hand-wave.&amp;nbsp; If I said anything at all I would say something like "a reference is actually implemented as a small chunk of data which contains information used by the CLR to determine precisely which object is being referred to by the reference". That's both vague and accurate without implying more than is wise.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9428097" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Books/default.aspx">Books</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Best+Of+FAIC/default.aspx">Best Of FAIC</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category></item></channel></rss>