Summary: in this tutorial, you’ll learn about C# value and reference types and how .NET stores the objects of the value and reference type in the memory.
Memory management
When a C# program runs, it stores data in the memory. Typically, a running program uses two main regions in the memory to store data:
- The stack
- The heap
The Stack
The stack is an array of memory that works based on the last-in, first-out (LIFO) principle. The stack allows you to add data to or remove data from the top of it:
The stack has two main operations, push and pop:
- Placing data at the top of the stack is called pushing.
- Removing data from the top of the stack is called popping.
The following picture illustrates a stack:
The stack stores the following type of data:
- Values of some variable types.
- Parameters passed to methods.
- The current execution environment of the program.
The Heap
The heap is a memory area where you can store a certain kind of data. Unlike the stack, data on the heap can be added or removed in any order.
The following picture illustrates the heap memory:
Typically, a program can store items in the heap, but it cannot delete them explicitly. Instead, the garbage collector (GC) automatically cleans up orphaned heap objects when it determines that the program no longer needs them.
The following picture shows that the program no longer references a piece of data on the heap:
The GC will start reclaiming it:
And after garbage collection, the memory is released for reuse:
C# value and reference types
C# divides types into two categories:
- Value types
- Reference types
And C# stores the objects of value types and reference types differently.
Value types require only a single location of memory that stores the actual data. C# stores objects of value types on the stack:
Examples of the value types are byte, short, short, int, long, bool, struct, and enum.
Reference types require two locations in memory:
- The first contains the actual data which always locates in the heap.
- The second is a reference that points to the actual data. C# stores the reference on the stack.
The following picture illustrates how C# stores an object of a reference type:
Examples of reference types are string, object, and user-defined types including class, interface, delegate, and array.
Storing members of an object of a reference type
C# always stores the actual data of an object of a reference type on the heap. It means that if the object has members which are value types, C# also stores the data of these members on the heap.
The following picture illustrates how C# stores the member of an object of a reference type:
Checking if a type is a value or reference type
To check if the type is a value or reference type, you use the typeof
operator to get the System.Type
instance of a type and check the IsValueType
property.
If the IsValueType
property returns true, the type is a value type. Otherwise, it is a reference type.
The following illustrates the use of the typeof
and IsValueType
property to check whether int
and string
are value or reference types:
using static System.Console;
WriteLine(typeof(int).IsValueType); // True
WriteLine(typeof(string).IsValueType); // False
Code language: C# (cs)
Output:
True
False
Code language: C# (cs)
Summary
- A running program uses two main regions of the memory: the stack and heap.
- The garbage collector automatically removes objects on the heap once the program no longer uses them.
- C# stores data of value types on the stack and data of reference types on the heap.