It seems like every .net book talks about value types vs reference types and makes it a point to (often incorrectly) state where each type is stored - the heap or the stack. Usually it's in the first few chapters and presented as some all-important fact. I think it's even covered on certification exams. Why does stack vs heap even matter to (beginner) .Net developers? You allocate stuff and it just works, right?
I'm becoming convinced that the primary reason this bit of information is considered important is tradition. In unmanaged environments, the disctinction between stack and heap is important and we have to manually allocate and delete the memory we use. Now, garbage collection takes care of the management, so they ignore that bit. I don't think the message has really gotten through that we don't have to care which type of memory is used either.
As Fede pointed out, Eric Lippert has some very interesting things to say about this: http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx.
In light of that information, you could adjust my first paragraph to basically read: "The reason people include this information and assume it is important is because of incorrect or incomplete information combined with needing this knowledge in the past."
For those who think it is still important for performance reasons: What actions would you take to move something from the heap to the stack if you did measure things and find out that it mattered? More likely, you'd find a completely different way of improving performance for the problem area.
I agree completely; I see this all the time.
One part of the reason is because many people came to C# (or other .NET languages) from a C or C++ background. Since those languages do not enforce for you the rules about storage lifetime, you are required to know those rules and implement your program carefully to follow them.
Now, knowing those rules and following them in C does not require that you understand "the heap" and "the stack". But if you do understand how the data structures work then it is often easier to understand and follow the rules.
When writing a beginner book it is natural for an author to explain the concepts in the same order that they learned them. That's not necessarily the order that makes sense for the user. I was recently technical editor for Scott Dorman's C# 4 beginner book, and one of the things I liked about it was that Scott chose a pretty sensible ordering for the topics, rather than starting in on what really are quite advanced topics in memory management.
Another part of the reason is that some pages in the MSDN documentation strongly emphasize storage considerations. Particularly older MSDN documentation that is still hanging around from the early days. Much of that documentation has subtle errors that have never been excised, and you have to remember that it was written at particular time in history and for a particular audience.
In my opinion, it doesn't. What is much more important to understand is stuff like:
And so on.
That's the ideal.
Now, there are situations in which it does matter. Garbage collection is awesome and relatively inexpensive, but it is not free. Copying small structures around is relatively inexpensive, but is not free. There are realistic performance scenarios in which you have to balance the cost of collection pressure against the cost of excessive copying. In those cases it is very helpful to have a strong understanding of the size, location, and actual lifetime of all relevant memory.
Similarly, there are realistic interop scenarios in which it is necessary to know what is on the stack and what is on the heap, and what the garbage collector could be moving around. That's why C# has features like "fixed", "stackalloc" and so on.
But those are all advanced scenarios. Ideally a beginner programmer need worry about none of this stuff.
As to WHY do they cover the topic, I agree with @Kirk that it's an important concept, that you have to understand. The better you know the mechanisms, the better you can do to make great applications that performs smoothly.
Now Eric Lippert seems to agree with you that the topic is not correctly covered by most authors. I recommend you read his blog to achieve a great understanding of what's under the hood.
You guys are all missing the point. The reason why the stack / heap distinction is important is because of scope.
Once x goes out of scope, the object that was created is categorically gone. That is only because it is allocated on the stack, not the heap. There is nothing that could have gone in in the "..." part of the method that can change that fact. In particular, any assignments or method calls could only have made copies of the S struct, not created new references to it to enable it to keep living.
Totally different story! Since x is now on the heap, its object (that is, the object itself, not a copy of it) could very well continue to live on after x goes out of scope. In fact, the only way it won't continue to live is if x is the only reference to it. If assignments or method calls in the "..." part have created other references that are still "live" by the time x goes out of scope, then that object will continue living.
That is a very important concept, and the only way to truly understand "what and why" is to know the difference between stack and heap allocation.
Well, I thought that's the whole point of managed environments. I'd even go as far as calling this an implementation detail of the underlying runtime that you should NOT make any assumptions about, because it could change at any time.
I don't know much about .NET, but as far as I know, its JITted before execution. The JIT for example could perform escape analysis and what not and all of a sudden you'd be having objects lying on the stack or merely in some registers. You cannot know this.
I suppose some books cover it simply because the authors attribute great importance to it, or because they assume their audience does (e.g. if you wrote a "C# for C++ programmers" you probably should cover the topic).
Nonetheless, I think there is not much more to say than "memory is managed". Otherwise people might draw wrong conclusions.
You have to understand how memory allocation works to use it efficiently even if you don't have to manage it explicitly. This applies to pretty much every abstraction in computer science.
|show 1 more comment|
There can be some edge cases where it that can make a difference. The default stack space is 1meg while the heap is several gig. So if you're solution holds a large number of object you can run out of stack space while having plenty of heap space.
However, for the most part it is pretty academic.