Foundations of Programming - Karl Seguin
Foundations of Programming - Karl Seguin
Foundations of Programming - Karl Seguin
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Chapter 7 - Back to Basics: Memory<br />
Back to Basics: Memory<br />
NOT 'GETTING' ALGEBRA IS NOT ACCEPTABLE FOR A MATHEMATICIAN, AS NOT<br />
'GETTING' POINTERS IS NOT ACCEPTABLE FOR PROGRAMMERS. TOO FUNDAMENTAL.<br />
- WARD CUNNINGHAM<br />
T<br />
ry as they might, modern programming language can't fully abstract fundamental aspects <strong>of</strong><br />
computer systems. This is made evident by the various exceptions thrown by high level<br />
languages. For example, it's safe to assume that you've likely faced the following .NET exceptions:<br />
NullReferneceException, OutOfMemoryException, StackOverflowException and<br />
ThreadAbortException. As important as it is for developers to embrace various high level patterns<br />
and techniques, it's equally important to understand the ecosystem in which your program runs.<br />
Looking past the layers provided by the C# (or VB.NET) compiler, the CLR and the operating system, we<br />
find memory. All programs make extensive use <strong>of</strong> system memory and interact with it in marvelous<br />
ways, it's difficult to be a good programmer without understanding this fundamental interaction.<br />
Much <strong>of</strong> the confusion about memory stems from the fact that C# and VB.NET are managed languages<br />
and that the CLR provides automatic garbage collection. This has caused many developers to<br />
erroneously assume that they need not worry about memory.<br />
Memory Allocation<br />
In .NET, as with most languages, every variable you define is either stored on the stack or in the heap.<br />
These are two separate spaces allocated in system memory which serve a distinct, yet complimentary<br />
purpose. What goes where is predetermined: value types go on the stack, while all reference types go<br />
on the heap. In other words, all the system types, such as char, int, long, byte, enum and any<br />
structures (either defined in .NET or defined by you) go on the stack. The only exception to this rule are<br />
value types belonging to reference types - for example the Id property <strong>of</strong> a User class goes on the heap<br />
along with the instance <strong>of</strong> the User class itself.<br />
The Stack<br />
Although we're used to magical garbage collection, values on the stack are automatically managed even<br />
in a garbage collectionless world (such as C). That's because whenever you enter a new scope (such as a<br />
method or an if statement) values are pushed onto the stack<br />
and when you exit the stack the values are popped <strong>of</strong>f. This is<br />
why a stack is synonymous with a LIFO - last-in first-out. You<br />
can think <strong>of</strong> it this way: whenever you create a new scope,<br />
say a method, a marker is placed on the stack and values are<br />
added to it as needed. When you leave that scope, all values<br />
are popped <strong>of</strong>f up to and including the method marker. This<br />
works with any level <strong>of</strong> nesting.<br />
<strong>Foundations</strong> <strong>of</strong> <strong>Programming</strong> Copyright © <strong>Karl</strong> <strong>Seguin</strong> www.codebetter.com<br />
53<br />
7<br />
If you've ever wondered why a<br />
variable defined in a for loop or if<br />
statement wasn't available outside<br />
that scope, it's because the stack<br />
has unwound itself and the value is<br />
lost.