C# manages memory allocation by creating its types in one of these locations: Heap, Stack, and Register.
A heap is a place in the RAM where dynamic allocations happen.
The stack is a Last In First Out (LIFO) bit of memory which is relatively smaller than the heap.
Categories | Stack | Heap |
Memory Allocation | Memory allocation is Static | Memory allocation is Dynamic |
How is it Stored? | It is stored Directly | It is stored indirectly |
Is Variable Resized? | Variables can’t be Resized | Variables can be Resized |
Access Speed | Its access is fast | Its access is Slow |
Visibility or Accessibility | It can be visible/accessible only to the Owner Thread | It can be visible/accessible to all the threads |
StackOverflowException | .NET Runtime throws exception “StackOverflowException” when stack space is exhausted | – |
The register is used to store computational values of an arithmetic operation and temporary Value Types and is the smallest of all the locations.
These four main types of things we’ll be putting in the Stack and Heap: Value Types, Reference Types, Pointers, and Instructions.
The type declarations for Value Types are bool, byte, char, decimal, double, enum, float, int, long, sbyte, short, struct, uint, ulong, ushort.
The type declarations for Reference Types are: class, interface, delegate, object, string.
A Reference is often referred to as a pointer.
Boxing and unboxing is an important concept in C#.
Boxing is the process of converting a value type to the object type or any interface type implemented by this value type.
Let’s see a simple example:
1 2 3 | int my_num = 76; // value type is int and assigned value 76 Object my_obj = my_num; // Boxing int my_num = 731976; // value of my_num to be change |
The process of converting reference type into the value type is known as Unboxing.
1 2 3 | int my_num = 76; // value type is int and assigned value 76 Object my_obj = my_num; // Boxing int i = (int)my_obj; // Unboxing |
Unboxing is the reverse of boxing and is the process of converting a reference type to a value type.
Let’s see another example:
1 2 | ArrayList my_list = new ArrayList(); my_list.Add(76); // Boxing because I add an int value 76 in it. |
Use List instead of ArrayList to avoid boxing because List‘s Add method actually takes an int parameter.
ArrayList is a class in C#, and so it is a reference type.
The .NET will perform the boxing process here to assign value type to reference type.
Boxing and unboxing degrade the performance.
Use generics to avoid boxing and unboxing using generic type.
The List<T> is the generic type.
This contains elements of the specified type and provides compile-time type checking and doesn’t perform boxing-unboxing because it is generic.