Click here to Skip to main content
Click here to Skip to main content

Six important .NET concepts: Stack, heap, value types, reference types, boxing, and unboxing

By , 14 May 2012
 

Table of contents

This video explains the concept of boxing and unboxing and it also shows the performance implications caused by the same.

Introduction

This article will explain six important concepts: stack, heap, value types, reference types, boxing, and unboxing. This article starts explaining what happens internally when you declare a variable and then it moves ahead to explain two important concepts: stack and heap. The article then talks about reference types and value types and clarifies some of the important fundamentals around them.

The article concludes by demonstrating how performance is hampered due to boxing and unboxing, with a sample code.

Watch my 500 videos on various topics like design patterns, WCF, WWF, WPF, LINQ, Silverlight, UML, SharePoint, Azure, VSTS, and a lot more: click here. You can also catch me on my trainings here.

Image taken from http://michaelbungartz.wordpress.com/.

What goes inside when you declare a variable?

When you declare a variable in a .NET application, it allocates some chunk of memory in the RAM. This memory has three things: the name of the variable, the data type of the variable, and the value of the variable.

That was a simple explanation of what happens in the memory, but depending on the data type, your variable is allocated that type of memory. There are two types of memory allocation: stack memory and heap memory. In the coming sections, we will try to understand these two types of memory in more detail.

Stack and heap

In order to understand stack and heap, let’s understand what actually happens in the below code internally.

public void Method1()
{
    // Line 1
    int i=4;

    // Line 2
    int y=2;

    //Line 3
    class1 cls1 = new class1();
}

It’s a three line code, let’s understand line by line how things execute internally.

  • Line 1: When this line is executed, the compiler allocates a small amount of memory in the stack. The stack is responsible for keeping track of the running memory needed in your application.
  • Line 2: Now the execution moves to the next step. As the name says stack, it stacks this memory allocation on top of the first memory allocation. You can think about stack as a series of compartments or boxes put on top of each other.
  • Memory allocation and de-allocation is done using LIFO (Last In First Out) logic. In other words memory is allocated and de-allocated at only one end of the memory, i.e., top of the stack.

  • Line 3: In line 3, we have created an object. When this line is executed it creates a pointer on the stack and the actual object is stored in a different type of memory location called ‘Heap’. ‘Heap’ does not track running memory, it’s just a pile of objects which can be reached at any moment of time. Heap is used for dynamic memory allocation.

One more important point to note here is reference pointers are allocated on stack. The statement, Class1 cls1; does not allocate memory for an instance of Class1, it only allocates a stack variable cls1 (and sets it to null). The time it hits the new keyword, it allocates on "heap".

Exiting the method (the fun): Now finally the execution control starts exiting the method. When it passes the end control, it clears all the memory variables which are assigned on stack. In other words all variables which are related to int data type are de-allocated in ‘LIFO’ fashion from the stack.

The big catch – It did not de-allocate the heap memory. This memory will be later de-allocated by the garbage collector.

Now many of our developer friends must be wondering why two types of memory, can’t we just allocate everything on just one memory type and we are done?

If you look closely, primitive data types are not complex, they hold single values like ‘int i = 0’. Object data types are complex, they reference other objects or other primitive data types. In other words, they hold reference to other multiple values and each one of them must be stored in memory. Object types need dynamic memory while primitive ones needs static type memory. If the requirement is of dynamic memory, it’s allocated on the heap or else it goes on a stack.

Image taken from http://michaelbungartz.wordpress.com/

Value types and reference types

Now that we have understood the concept of Stack and Heap, it’s time to understand the concept of value types and reference types. Value types are types which hold both data and memory on the same location. A reference type has a pointer which points to the memory location.

Below is a simple integer data type with name i whose value is assigned to another integer data type with name j. Both these memory values are allocated on the stack.

When we assign the int value to the other int value, it creates a completely different copy. In other words, if you change either of them, the other does not change. These kinds of data types are called as ‘Value types’.

When we create an object and when we assign an object to another object, they both point to the same memory location as shown in the below code snippet. So when we assign obj to obj1, they both point to the same memory location.

In other words if we change one of them, the other object is also affected; this is termed as ‘Reference types’.

So which data types are ref types and which are value types?

In .NET depending on the data type, the variable is either assigned on the stack or on the heap. ‘String’ and ‘Objects’ are reference types, and any other .NET primitive data types are assigned on the stack. The figure below explains the same in a more detail manner.

Boxing and unboxing

Wow, you have given so much knowledge, so what’s the use of it in actual programming? One of the biggest implications is to understand the performance hit which is incurred due to data moving from stack to heap and vice versa.

Consider the below code snippet. When we move a value type to reference type, data is moved from the stack to the heap. When we move a reference type to a value type, the data is moved from the heap to the stack.

This movement of data from the heap to stack and vice-versa creates a performance hit.

When the data moves from value types to reference types, it is termed ‘Boxing’ and the reverse is termed ‘UnBoxing’.

If you compile the above code and see the same in ILDASM, you can see in the IL code how ‘boxing’ and ‘unboxing’ looks. The figure below demonstrates the same.

Performance implication of boxing and unboxing

In order to see how the performance is impacted, we ran the below two functions 10,000 times. One function has boxing and the other function is simple. We used a stop watch object to monitor the time taken.

The boxing function was executed in 3542 ms while without boxing, the code was executed in 2477 ms. In other words try to avoid boxing and unboxing. In a project where you need boxing and unboxing, use it when it’s absolutely necessary.

With this article, sample code is attached which demonstrates this performance implication.

Currently I have not included source code for unboxing but the same holds true for it. You can write code and experiment it using the stopwatch class.

Source code

Attached with the article is a simple code which demonstrates how boxing creates performance implications. You can download the source code here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Shivprasad koirala
Architect http://www.questpond.com
India India
Member

I am a Microsoft MVP for ASP/ASP.NET and currently a CEO of a small
E-learning company in India. We are very much active in making training videos ,
writing books and corporate trainings. Do visit my site for 
.NET, C# , design pattern , WCF , Silverlight
, LINQ , ASP.NET , ADO.NET , Sharepoint , UML , SQL Server  training 
and Interview questions and answers


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralGreatmembermcdave99926 Jan '13 - 1:01 
What a well written article. Thanks!
GeneralMy vote of 5memberahmed_am5515 Jan '13 - 6:32 
Fascinating
GeneralMy vote of 5memberK.NAVEENBAABU28 Dec '12 - 8:17 
Clearly Explained with simple language and code.
 
(Is this BpB Publications Author Sivprasad Koirala?
I need .Net Int'QA DVDs Cash on delivery is available?)
GeneralMy vote of 5memberAttiq-ul-Islam19 Dec '12 - 23:16 
Nice commentary
GeneralExcellentmemberMember 940922113 Dec '12 - 17:49 
Excellent
Questionlike itmemberHua Yujun5 Dec '12 - 20:42 
thanks!
I like programing

GeneralMy vote of 3memberFabián García30 Nov '12 - 7:21 
Good for remember some notes of the school Smile | :)
GeneralMy vote of 5memberRohan Leuva21 Nov '12 - 18:17 
read this one time for lifetime.One of the most important and valueable article on the web.Thanks for the same.
GeneralMy vote of 5memberSyedur Rahaman17 Nov '12 - 21:05 
Excellent...
GeneralMy vote of 5membersudheer muhammed15 Nov '12 - 0:23 
Beautifully explained.
Questionnicely done!memberlookitstony30 Oct '12 - 7:48 
I have struggled with truly understanding the information in this post and you have made it crystal clear for me now. Thanks keep up the great job!
GeneralMy vote of 5membermaheshbisht29 Oct '12 - 23:09 
Awesome nothing can be better from it.....really
QuestionNice Articlememberarunsurfer22 Oct '12 - 21:02 
Its one of the finest articles i read it about Stack and heap Smile | :)
GeneralExcellent!memberzhengwb18 Oct '12 - 21:29 
Thanks,it's really easy to understand! Smile | :)
GeneralMy vote of 5membersoulprovidergr18 Sep '12 - 4:14 
Excellent!
GeneralMy vote of 5memberRaveesh15 Sep '12 - 6:20 
Very easy to understand
GeneralMy vote of 4memberArun Babu A15 Sep '12 - 1:29 
very good article written in an easily
understandable way
QuestionNicely presented.memberKChandos9 Aug '12 - 5:28 
What tool are you using for creating your graphics? I like how they present.
Questionboxing or unboxingmembergagan sawaliya9 Aug '12 - 2:54 
If we store value in session then what is it call boxing or unboxing?
pls tell me
GeneralMy vote of 5membergagan sawaliya9 Aug '12 - 2:49 
nice
GeneralMy vote of 5memberGuyThiebaut23 Jul '12 - 9:41 
Very nice - thanks!
GeneralMy vote of 5memberAlecoder23 Jul '12 - 3:49 
Thank you for this article !
GeneralMy vote of 5membermassiah310012 Jul '12 - 23:41 
Excellent article! Using nothing but visual .net for too long, it's easy to forget what's going on behind the scenes, this was a great refresher
QuestionvisitmemberAnnieCalvert12 Jul '12 - 2:50 
If you need some help regarding .net,c# .Visit this site.
http://www.dapfor.com/en/net-suite/net-grid/tutorial/data-types
QuestionMy Vote of 5!memberakosidab20 Jun '12 - 21:01 
Plain and Simple! The Best!
Regards,
David

GeneralMy vote of 4memberbrigano17 Jun '12 - 21:51 
Very clear explanation of boxing with a simple example!
GeneralMy vote of 5memberMohammad A Rahman22 May '12 - 17:44 
My 5. Nice
GeneralMy vote of 5memberkumuda.t21 May '12 - 21:42 
Realtime example shows performance issues when doing boxing & unboxing. it is very simple & clear.
Question[My vote of 2] inaccuracies or poor wordings.memberJay R. Wren21 May '12 - 11:40 
"When you declare a variable in a .NET application, it allocates some chunk of memory in the RAM. This memory has three things: the name of the variable, the data type of the variable, and the value of the variable."
 
The name and type of a local variable is never stored.
e.g.
class Program {
public static void Main() {
int x = 1;
Console.Write(x);
}
}
 
The name "x" above is stored only the PDB for the debugger. It is not part of the .net assembly. The memory is allocated as a local for the main method. The IL looks like this:
 
.locals init (
int32 V_0)
 
The type is not stored in the memory allocated for the object, it is known at runtime by the IL code we are exectuing. See the int32 there in the IL. The only stack memory used is the 32bits to store the integer.
 
The next issue is maybe a problem with mixing the theoretical teaching of the stack v. the C# implementation without getting too complex.
 
In the Stack and Heap section with an example Method1 you say
"Line 1: When this line is executed, the compiler allocates a small amount of memory in the stack. The stack is responsible for keeping track of the running memory needed in your application."
 
This is not really true. It is not true because this line is never directly executed. The C# compiler compiles this code to IL. Then the .NET Runtime JITs the IL to X86 or X64 code depending on platform when the assembly is executed.
 
Compilers doesn't "allocate a small amount of memory in the stack" when running an application. Compilers don't run applications. Compilers turn source code into machine code or in this case an intermediate language.
 
The next thing this article says is that Line 2 happens and more stack is allocated, but this is not at all what actually happens.
 
What actually happens is that the Compiler generates IL which allocates all of the stack space that this method will ever use upon entry point of the method. That is, when the method is called, the stack is allocated with the parameters, return parameters and locals for this method.
 
For Line 3, yes, the new call does heap allocate an instance of class1, but also the reference to that is a local stack allocated memory location. That is, cls1 is a reference on the stack as soon as Method1 is called. cls1 has an unknown value until it is assigned the reference to the heap allocated class1 when the code which was compiled from the source on line 3 is executed.
 
This makes the pictures misleading because the pictures suggest that the stack grows as the method executes. This is not true. The stack grows only when a method is called.
 
"If you look closely, primitive data types are not complex,"
 
just a nit-pic here, the C# Language specification doesn't use the word "primitive" so I tend to avoid it when discussing the C# language. Prefer the phrase "simple type". See Chapter 4 of the C# 4.0 Language Specification for detail.
 
The nice image of the hierarchy of types under "So which data types are ref types and which are value types?" I think you meant "Simple Types" instead of "Simply Types".
 
For clarity: The image with the chimpanzee which says "static memory ?" and "Dynamic memory ?" could be confusing. I've always found "static allocation" and "dynamic allocation" to be more clear. "Static Memory" makes me think of static ram and so Static Memory and Dynamic Memory sound like SRAM and DRAM which are a completely different subject.
 
Kudos for tackling such a difficult topic to communicate.
GeneralMy vote of 5memberShilpa Gurnani16 May '12 - 2:31 
Really Cleared My concepts about stack and heap
GeneralMy vote of 5memberOshtri Deka15 May '12 - 22:13 
5!
This is a obligatory reading for all .Net beginners.
Comprehensive, accurate and has a picture of monkey! Smile | :)
 
I must admit that I've had "honor" of meeting so-called developers with such gaps in above mentioned fundamentals. If I'll had to repeat such experience I'll gladly point them to this article.
QuestionHow string datatype allocates memory?memberRavi Mori15 May '12 - 21:32 
Hi,
I have one question. How string data type allocates memory? I have this question because you mentioned that string is a reference type. So will it allocate on memory in heap and pointers will store in stack?
AnswerRe: How string datatype allocates memory?memberRavi Mori15 May '12 - 23:14 
Got my answer in below link:
http://forums.asp.net/t/1755004.aspx/1[^]
 
Nice Article..!!!
QuestionMy vote of 5membershanmugarajaa15 May '12 - 20:40 
Excellent! As a beginner, your article is very much informative to understand about the concept of stack, heap, Boxing and Unboxing.
In the same way you have the concept explanation for C++? because I am working in VC++ and I always looking to learn c++ concept indepth.I have visited your cited site.But still I can't find any source for C++..
 
Can you help me...
 
Thanks and Regards,
S.Shanmugaraja
GeneralMy vote of 5memberRahul.KumarSharma15 May '12 - 19:23 
Good article.
GeneralMy vote of 5member_Zorro_14 May '12 - 21:44 
Nice article
QuestionMy vote of 5memberegenis14 May '12 - 18:26 
Great read! Plain and simple and easy to understand!
Well done
QuestionExcellent tutorial...memberMember 47338069 Apr '12 - 8:29 
Iam impressed with your articles and I think I tend to follow your steps in .NET
jjjj

GeneralMy vote of 5memberonurag198 Apr '12 - 22:03 
Excellent Mast Hai
GeneralMy vote of 5memberbeginner201120 Mar '12 - 16:45 
nice
GeneralMy vote of 5memberGentlemanK5 Mar '12 - 21:39 
very very well explained...
GeneralMy vote of 5memberPetr Abdulin4 Mar '12 - 19:24 
Good explanation for beginners.
GeneralMy vote of 5memberkarthy Udhaykumar27 Feb '12 - 20:18 
good article for begineers.
GeneralMy vote of 5memberramanayadavs27 Feb '12 - 0:27 
Thank you very much BOSS !!!!
GeneralMy vote of 5memberfran_hemida24 Feb '12 - 10:27 
Nice article, especially for beginners like me
SuggestionNice article, but is stack vs heap that important? [modified]memberRiz Thon20 Feb '12 - 14:07 
For me the difference between value type and reference type is really important, because it can cause weird bugs if you don't know about it ("why isn't my object being updated?").
 
Then boxing/unboxing is less important, especially if you're only considering performances. Of course the perf will be lower if you're always boxing and unboxing, but most people won't be doing intensive stuffs and won't notice the difference. You should only start thinking about optimizing if things don't go fast enough.
Though, you can again have weird bugs if you don't know about it: it happened to me not that long ago, where I had a uint, and I was comparing it to something coming from a generic UI editor, that was converting the value from a string and returning an object. The problem was that the value from the string was converted into an int (int32), and then boxed. Thus eventually I was trying to compare a uint to a boxed int, which will never work. So for me that kind of problem is more important that the performace impact (unless you're in the critical path and you're really doing tons of boxing/unboxing all the time).
 
Eventually, stack and heap is really not important to me. I don't feel like anyone should know what's happening at such a low level. Also it really depends on the implementation, so maybe what you described is what is happening on .Net 4.0, but maybe something else is happening on 1.1 or will happen in 5.0, or in Mono. Here is an article from Eric Lippert called "The Stack Is An Implementation Detail"
The Stack Is An Implementation Detail, Part One[^]
The Stack Is An Implementation Detail, Part Two[^]

modified 21 Feb '12 - 19:31.

GeneralRe: Nice article, but is stack vs heap that important?memberShivprasad koirala4 Apr '12 - 3:12 
Riz you are so right. I think performance is not so important but the defect arising can be.
 
Erics links are great and the one genuine source value types and ref types.
My book .NET interview questions with 500 mostly asked questions in .NET world .NET Interview questions and answers

GeneralMy vote of 5membersumithpdgp20 Feb '12 - 7:22 
Good explaination, and choice of images and drawings.
GeneralMy vote of 5memberVijay Chandra Sekhar Parepalli20 Feb '12 - 7:06 
Good and clear explanation, Shivprasad.
GeneralMy vote of 5memberVinod Satapara14 Feb '12 - 20:13 
Excellent

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 14 May 2012
Article Copyright 2010 by Shivprasad koirala
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid