.NET WeakReference Is Not Pinned
This content was translated from Korean using AI.

High-Performance Server Blog Post

The following blog has been very helpful in profiling and improving the performance of a C# game server.

C# High-Performance Server - Memory Fragmentation | leafbird/devnote

In the article, it mentioned that WeakReference creates memory pinning, which raised a question: if memory is pinned, wouldn't that mean WeakReference strongly references the memory it points to, thus rendering WeakReference meaningless?

`System.WeakReference` also uses pinned handles, which can cause fragmentation.

WeakReference Does Not Pin Memory

To get straight to the point, WeakReference does not pin memory.

I searched on Google and ChatGPT but couldn't find any information linking WeakReference to pinned handles. So, I decided to leave a dump as mentioned in the blog post to check the .NET handles.

After creating 10,000 WeakReferences and checking the handles in the dump, I found that there were 10,000 Weak Short handles, not pinned handles.

8_handles1.png

8_handles2.png

For reference, types like Weak Short and Weak Long are used internally by the .NET runtime, which is written in C++. You can find more information in the runtime/src/coreclr/gc/gcinterface.h at main · dotnet/runtime · GitHub.

The accessible handle types in .NET are as follows, and WeakReference uses either the Weak or WeakTrackResurrection type depending on the creation options.

public enum GCHandleType
{
	Weak,
	WeakTrackResurrection,
	Normal,
	Pinned,
}

In any case, WeakReference does not pin memory and therefore does not contribute to memory fragmentation.

Of course, there is a cost associated with managing the handle table in the .NET runtime and the cost of modifying the pointers to handles when the garbage collector runs, so creating too many handles may not be advisable.