reading-notes

View on GitHub

Heap and Stack

There are two places the .NET framework stores items in memory as your code executes. If you haven’t already met, let me introduce you to the Stack and the Heap. Both the stack and heap help us run our code. They reside in the operating memory on our machine and contain the pieces of information we need to make it all happen.

Stack vs. Heap: What’s the difference?

The Stack is more or less responsible for keeping track of what’s executing in our code (or what’s been “called”). The Heap is more or less responsible for keeping track of our objects.

Think of the Stack as a series of boxes stacked one on top of the next. We keep track of what’s going on in our application by stacking another box on top every time we call a method (called a Frame). We can only use what’s in the top box on the stack. When we’re done with the top box (the method is done executing) we throw it away and proceed to use the stuff in the previous box on the top of the stack. The Heap is similar except that its purpose is to hold information (not keep track of execution most of the time) so anything in our Heap can be accessed at any time.

What goes on the Stack and Heap?

We have four main types of things we’ll be putting in the Stack and Heap as our code is executing: Value Types, Reference Types, Pointers, and Instructions.

Value Types

In C#, all the “things” declared with the following list of type declarations are Value types (because they are from System.ValueType):

Reference Types

All the “things” declared with the types in this list are Reference types (and inherit from System.Object… except, of course, for object which is the System.Object object):

Pointers

The third type of “thing” to be put in our memory management scheme is a Reference to a Type. A Reference is often referred to as a Pointer. We don’t explicitly use Pointers, they are managed by the Common Language Runtime (CLR). A Pointer (or Reference) is different than a Reference Type in that when we say something is a Reference Type is a means we access it through a Pointer. A Pointer is a chunk of space in memory that points to another space in memory. A Pointer takes up space just like any other thing that we’re putting in the Stack and Heap and its value is either a memory address or null.

How is it decided what goes where? (Huh?)

Here are our two golden rules: A Reference Type always goes on the Heap - easy enough, right? Value Types and Pointers always go where they were declared. This is a little more complex and needs a bit more understanding of how the Stack works to figure out where “things” are declared. The Stack, as we mentioned earlier, is responsible for keeping track of where each thread is during the execution of our code (or what’s been called). You can think of it as a thread “state” and each thread has its own stack. When our code makes a call to execute a method the thread starts executing the instructions that have been JIT-compiled and live on the method table, it also puts the method’s parameters on the thread stack. Then, as we go through the code and run into variables within the method they are placed on top of the stack.