Stack and Heap in .NET Application with Examples
In this article, I am going to discuss Stack and Heap in .NET Application with examples. Please read our previous article, where we discussed Checked and unchecked keyword in C#. As part of this article, first we will discuss what happens internally when we declare a variable of value types as well as reference types. Then we will move forward and learn two important concepts i.e. stack and heap memory as well as we will talk about value types and reference types.
What happens internally when we declare a variable in .NET Application?
When we declare a variable in a .NET application, it allocates some memory in the RAM. The memory which it allocates in RAM has three things are as follows:
- Name of the variable,
- Data type of the variable, and
- Value of the variable.
For better understanding, please have a look at the following image. Here, we declare a variable of type int and assign a value 101.
The above image shows a high level overview of what happening in the memory. But depending on the data type (i.e. depending on the value type and reference type ), the memory may allocated either in the stack or in the heap memory.
Understanding Stack and Heap Memory in .NET:
There are two types of memory allocation for the variables that we created in .NET Application i.e. stack memory and heap memory.
Let us understand the stack and heap memory with an example. In order to understand stack and heap, please have a look at the following code and let’s understand what actually happens in the below code internally.
As you can see in the above image, the SomeMethod having three statements, let’s understand statement by statement how things executed internally.
When the first statement is executed, the compiler allocates a some memory in the stack. The stack memory is responsible for keeping track of the running memory needed in your application. For better understanding, please have a look at the following image.
When the second statement is executed, it stacks this memory allocation (memory allocation for variable y) on top of the first memory allocation (memory allocation for variable x). You can think about the stack as a series of plates or dishes put on top of each other. Please have a look at the following diagram for better understanding.
The Stack Memory allocation and de-allocation in .NET is done using the Last In First Out principle. In other words we can say that the memory allocation and de-allocation is done only at one end of the memory, i.e., top of the stack.
In the 3rd statement, we have created an object of SomeClass. When the 3rd statement is executed, it internally creates a pointer on the stack memory and the actual object is stored in a different memory location called as Heap memory. The Heap memory location does not track running memory. Heap is used for dynamic memory allocation. For better understanding please have a look at the below image.
Note: The reference pointers are allocated on stack. The statement, SomeClass cls1 does not allocate any memory for an instance of SomeClass, it only allocates a variable with the name cls1 in the stack and set its value to null. The time it hits the new keyword, it allocates on the memory in the heap.
What happens when the method complete its execution?
When the three statements are executed, then the control will exist from the method. When it passes the end control i.e. the end curly brace “}”, it will clear all the memory variables which are created on stack. It will de-allocated the memory in ‘LIFO’ fashion from the stack. For better understanding please have a look at the below image.
Note: It will not de-allocate the heap memory. Later, the heap memory will be de-allocated by the garbage collector.
Now you may have one question in your mind that is why two types of memory, can’t we just allocate everything on just one memory type?
Why we have two types of memory?
As we know, in C#, the primitive data types such as int, double, bool, etc. they just hold a single value. On the other hand, the reference data types or object data types are complex. I.e. an object data type or reference data type can have reference to other objects as well as other primitive data types.
So, the reference data type hold references to other multiple values and each one of them must be stored in memory. Object types need dynamic memory while primitive data types needs static memory. Please have a look at the following image for better understanding.
Value types and reference types in .NET
As we understood the concept of Stack and Heap, Now, let us move forward and understand the concept value types and reference types in detail.
The Value types are the types which hold both data and memory on the same location. On the other hand, a reference type is a type which has a pointer which points to the actual memory location.
Understanding Value Type:
Let us understand value type with an example. Please have a look at the following image. As you can see in the image, first we create an integer variable with the name x and then we assign this x integer value to another integer variable whose name is y. In this both these memory values are allocated on the stack.
In .NET, when we assign one integer variable value to the another integer variable, then it creates a completely different copy in the stack memory that’s what you can see in the above image.So, if you change either variables value, then the other variable will not be affected. In .NET this kinds of data types are called as ‘Value types’. So, bool, byte, char, decimal, double, enum, float, long, sbyte, int, short, ulong, struct, uint, ushort are the examples of value types.
Understanding Reference Type:
Let us understand reference type with an example. Please have a look at the following image. Here, first we create an object i.e. obj1) and then assign this object to another object i.e. obj2. In this case both reference variable (obj1 and obj2) will point to the same memory location.
In this case, when you change one of them, the other object is also gets affected. This kind of data types are termed as ‘Reference types’ in .NET. So, class, interface, object, string and delegate are the example of Reference Types.
How is the heap memory freed up?
The memory allocation which are done on the stack are gone when the control moves out from the method i.e once the method complete its execution. On the other hand, the memory allocation which is done on heap, needs to be de-allocated by garbage collector.
When an object stored on the heap no longer use that the object does not have any references pointing, then the object is eligible for garbage collection. At a some point of time, the garbage collector will de-allocates this object from the heap.
In the next article, I am going to discuss Boxing and Unboxing in .NET with examples. Here, in this article, I try to explain Stack and Heap in C# with some examples. I hope you enjoy this article. I would like to have your feedback. Please post your feedback, question, or comments about this article.