C# Memory Management — Part 3 (Garbage Collection)

Sena Kılıçarslan
C# Programming
Published in
5 min readMar 20, 2019

I am writing this post as the last part of the C# Memory Management (Part 1 & Part 2) series. This post explains what the Garbage Collector does and how it works in the .NET environment. (Most of the information presented here is cited from Microsoft documentation)

First, let’s start with Common Language Runtime.

Common Language Runtime

The .NET Framework provides a run-time environment called the Common Language Runtime (CLR), which runs the code and provides services that make the development process easier.

The following illustration shows the relationship of the CLR and the class library to your apps and to the overall system.

Source : https://docs.microsoft.com/tr-tr/dotnet/framework/get-started/overview

The components of the CLR are:

Source : https://www.slideshare.net/Thenmurugeshwari/architecture-of-net-framework

In the CLR, the Garbage Collector serves as an automatic memory manager. C# and other languages on top of the CLR are garbage collected.

Garbage Collector

.NET’s Garbage Collector (GC) manages the allocation and release of memory for your application.

GC provides the following benefits:

  • Enables you to develop your application without having to free memory.
  • Allocates objects on the managed heap efficiently.
  • Reclaims objects that are no longer being used, clears their memory, and keeps the memory available for future allocations.
  • Provides memory safety by making sure that an object cannot use the content of another object.

All processes on the same computer share the same physical memory. Each process has its own, separate virtual address space. As an application developer, you work only with virtual address space and never manipulate physical memory directly. The GC allocates and frees virtual memory for you on the managed heap.

The heap can be considered as the accumulation of two heaps: the large object heap and the small object heap. The large object heap contains very large objects that are 85,000 bytes and larger (The objects on the large object heap are usually arrays).

Garbage collection gets triggered when one of the following conditions is true:

  • The system has low physical memory.
  • The memory that is used by allocated objects on the managed heap surpasses an acceptable threshold.
  • The GC.Collect method is called. (In almost all cases, you do not have to call this method, because the garbage collector runs continuously. This method is primarily used for unique situations and testing.)

Before a garbage collection starts, all managed threads are suspended except for the thread that triggered the garbage collection.

Source: https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals

Generations

In 1984 David Ungar came up with a generational hypothesis which gave birth to the generational garbage collectors:

Young objects die young. Therefore reclamation algorithm should not waste time on old objects.

Copying survivors is cheaper than scanning corpses.

The heap is organized into generations so it can handle long-lived and short-lived objects. There are three generations of objects on the heap:

Generation 0: This is the youngest generation and contains short-lived objects. An example of a short-lived object is a temporary variable. Garbage collection occurs most frequently in this generation.

Newly allocated objects form a new generation of objects and are implicitly Gen 0 collections unless they are large objects, in which case they go on the large object heap in a Gen 2 collection.

Most objects are reclaimed for garbage collection in Gen 0 and do not survive to the next generation. Objects that survive a Gen 0 garbage collection are promoted to Gen 1.

Generation 1: This generation contains short-lived objects and acts as a buffer between short-lived objects and long-lived objects. Objects that survive a Gen 1 garbage collection are promoted to Gen 2.

Generation 2: This generation contains long-lived objects. An example of a long-lived object is an object in a server application that contains static data that lives for the duration of the process. Objects that survive a Gen 2 garbage collection remain in Gen 2.

Collecting a generation means collecting objects in that generation and all its younger generations. A Gen 2 garbage collection is also known as a full garbage collection because it reclaims all objects in all generations.

How Garbage Collector Works

A garbage collection has the following phases:

Marking : Finds and creates a list of all live objects.

Relocating : Updates the references to the objects that will be compacted.

Compacting : Reclaims the space occupied by the dead objects and compacts the surviving objects. The compacting phase moves objects that have survived a garbage collection toward the older end of the segment. (Ordinarily, the large object heap is not compacted, because copying large objects imposes a performance penalty.)

The GC uses the following information to determine whether objects are live:

  • Stack roots: Stack variables provided by the just-in-time (JIT) compiler and stack walker.
  • Garbage collection handles: Handles that point to managed objects and that can be allocated by user code or by the CLR.
  • Static data: Static objects in application domains that could be referencing other objects.
Source: https://www.csharpstar.com/interview-questions-garbage-collection-csharp/

In addition, there are unmanaged resources like file streams, network/database connections that you need to take special care of. You need to use Finalizer & Dispose in this case. You can refer to this post for further information.

Lastly, I recommend you watch the below video which explains the topic visually with a very helpful demonstration at the end.

I hope you found this post helpful and easy to understand. As I mentioned in the beginning, this was the last part of the C# Memory Management series. If you are interested, you can read the other posts (Part 1 & Part 2) as well.

THE END :)

References

https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/

https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals

https://chodounsky.net/2017/05/03/garbage-collection-in-c-sharp/

--

--

Sena Kılıçarslan
C# Programming

A software developer who loves learning new things and sharing these..