dotMemory 2017.2 Help

.NET Memory Management Concepts

To work with dotMemory effectively, you must have a general understanding about how .NET manages memory. The following lists summarize .NET memory concepts. For additional information, you may refer to MSDN or other materials in the Web.

Memory Allocation

  • Garbage Collector (GC) is the part of the .NET framework that allocates and releases memory for your .NET applications.
  • When a new process is started, the runtime reserves a region of address space for the process called the managed heap.
  • Objects are allocated in the heap contiguously one after another.
  • Memory allocation is a very fast process as it is just the adding of a value to a pointer.
  • In addition to the managed heap, an app always consumes some amount of so-called unmanaged* memory which is not managed by GC.
    *Generally, it is required by .NET Common Language Runtime itself, dynamic libraries employed by the app, graphics buffer, and so on.

Memory Release

  • The process of releasing memory is called garbage collection.
  • When GC performs a collection, it releases only objects that are no longer in use by the application (for example, a local variable in a method can be accessed only during the method execution and after this, the variable is no longer needed).
  • To determine whether the object is used or not, GC examines application’s roots - strong references that are global to the application. Typically, these are global and static object pointers, local variables, and CPU registers. Learn more about possible GC roots inAnalyzing GC Roots.
  • For each active root, GC builds a graph that contains all the objects that are reachable from these roots.
  • If an object is unreachable, GC considers it no longer in use and removes the object from the heap (releases the memory occupied by the object).
  • After the object is removed, GC compacts reachable objects in memory.
    /help/img/dotnet/2017.2/basic_concepts_1.png

Generations

  • For better performance of memory release, the managed heap is divided into segments called generations: 0, 1, and 2.
  • When objects are just created, they are placed to the Generation 0 (Gen 0).
  • When Gen 0 is full (the size of the heap and generations is defined by GC), GC performs a garbage collection. During the collection, GC removes all unreachable objects from the heap. All reachable objects are promoted to the Generation 1 (Gen 1).
  • The Gen 0 collection is a rather quick operation.
  • When Gen 1 is full, the Gen 1 garbage collection is performed. All objects that survive the collection are promoted to Gen 2. The Gen 0 collection also takes place here.
  • When Gen 2 is full, GC performs full garbage collection. First, Gen 2 collection is performed, after this, the Gen 1 and Gen 0 collections take place. If there is still not enough memory for new allocations, GC raises the OutOfMemory exception.
  • During full garbage collection, GC has to pass through all objects in the heap, so, this process might have a great impact on system resources.
    /help/img/dotnet/2017.2/basic_concepts_2.png

Large Object Heap

  • Due to performance reasons, large objects (>85KB) are stored in a separate segment of the managed heap called Large Object Heap (LOH).
  • Survived objects in LOH are not compacted*. This means that LOH becomes fragmented over time.
    /help/img/dotnet/2017.2/basic_concepts_3.png

*Starting from .NET Framework 4.5.1, you can force GC to compact LOH during the full garbage collection.


Last modified: 29 August 2017

See Also