DEV Community

Cover image for What is GCHandle in C#? (Part 1)
Armin Shoeibi
Armin Shoeibi

Posted on

What is GCHandle in C#? (Part 1)

What is a WeakReference in C#? To fully understand it, we first need to delve into the internals of the platform, specifically GCHandle. Understanding GCHandle is crucial before we explore WeakReference and WeakReference<T>

GCHandle is a struct that helps us communicate with the .NET runtime (mostly GC) using P/Invoke. It’s been around since .NET Framework 1.1, but these days, it uses the modern LibraryImport instead of the older DllImport.

  1. GCHandle.cs
  2. GCHandle.Mono.cs
  3. GCHandle.CoreCLR.cs
  4. GCHandle.NativeAot.cs

If you want to see them all at a glance click

It is a partial struct with 2 properties.

  1. You can't instantiate it using the new keyword.
  2. You can new it up by calling the Alloc method, it accepts 2 parameters.
  3. The Alloc method needs the object reference and the type of Handle.
  4. It has four types: Weak, WeakTrackResurrection, Normal, or Pinned.
  5. Some of its methods are internal and not available for use in our applications.
  6. It uses System.IntPtr or nint.
  7. It employs the LibraryImport attribute, a new way of using DllImport.
  8. It uses the extern keyword.
  9. It involves the use of pointers.
  10. It utilizes the MethodImpl attribute.
  11. it calls this C++ code

Enough theory, Let's write some code with WeakType and check the available properties and methods.

  1. Create a Customer object.
  2. Create a GCHandle with a Weak type and reference to the customer.
  3. Print the allocation status and check if the target is not null.
  4. Retrieve and print the IntPtr(address) representation of the GCHandle.

Let's go and check it out in a real-world situation.

  1. Create an object from Customer.
  2. Create a Weak GCHandle for the Customer object.
  3. *Print * the customer object and leave the scope (CreateCustomerAndPrintIt method).
  4. Force GC to collect unreferenced objects.
  5. Check the Target property of GCHandle it should be null if the Customer has been garbage collected.

Tip:

After garbage collection, the Target property of a GCHandle can become null because the object has been collected. However, IsAllocated stays true because it only checks if the handle field (a memory address) is non-zero. The memory address doesn’t reset, even if the target object is gone.

You might be wondering, "So what?" 😁 What did we solve? We'll see soon enough.
To give you a quick hint: caching! It helps us cache references without causing memory leaks or consuming too much memory in critical applications.

Want something more to think about? I'll tell you: ConditionalWeakTable<TKey, TValue> uses the same infrastructure.

Let's explore other types of GCHandle in the next post. (WeakTrackResurrection, Normal and Pinned)

Top comments (0)