Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

182
Views
Garbage collection behaviour difference between .NetFramework 4.8 and .Net 5

To detect potential memory-leaks in places where it already happened a lot I have work with tests that are build like the shown below. The main idea is to have an instance, not reference it any longer and let the garbage collector collect it. I would like not to focus on whether this is a good technique or not (in my particular case it did an excellent job) but I would like to focus on the following question:

The code below works perfectly on .NetFramework 4.8 but does not on .Net 5. Why?

[Test]
public void ConceptualMemoryLeakTest()
{
    WeakReference weakReference;
    {
        object myObject = new object();
        weakReference = new WeakReference(myObject);
        myObject = null;
        Assert.Null(myObject);
    }
    Assert.True(weakReference.IsAlive); // instance not collected by GC
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.WaitForFullGCComplete();
    GC.Collect();
    Assert.False(weakReference.IsAlive); // instance collected by GC
}

You can see the main idea is to work with a WeakReference and use IsAlive to determine whether the instance got removed by the GC. How did the rules in the new CLR (the one originating from dotnet core) change? I know that what is done here does not relay on something that is specified. Rather I just exploit the behavior I see with the CLR in NetFramework 4.8.

Do you have an idea how to get something similar again that works also with .Net 5?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

The reason is likely tiered compilation. In simple words, tiered compilation will (for some methods under some conditions) first compile crude, low optimized version of a method, and then later will prepare a better optimized version if necessary. This is enabled by default in .NET 5 (and .NET Core 3+), but is not available in .NET 4.8.

In your case the result is your method is compiled with mentioned "quick" compilation and is not optimized enough for your code to work as you expect (that is lifetime of myObject variable extends until the end of the method). That is the case even if you compile in Release mode with optimizations enabled, and without any debugger attached.

You can disable tiered compilation by adding:

<TieredCompilation>false</TieredCompilation>

To some <PropertyGroup> inside csproj file for your .NET 5 project, then you'll observe the same behaviour you have in .NET 4.8 case.

Another alternative (besides moving variable to another method and returning WeakReference from it) is to use:

[MethodImpl(MethodImplOptions.AggressiveOptimization)]

attribute on ConceptualMemoryLeakTest method.

over 4 years ago · Santiago Trujillo Report

0

Actually with hints provided in the comments and answers I realized that moving the instance to a separate method and prevent in-lining it works:

[MethodImpl(MethodImplOptions.NoInlining)]
private WeakReference CreateWeakReference()
{
    object myObject = new object();
    return new WeakReference(myObject);
}

[Test]
public void ConceptualMemoryLeakTest()
{
    WeakReference weakReference = CreateWeakReference();
    Assert.True(weakReference.IsAlive);
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.WaitForFullGCComplete();
    GC.Collect();
    Assert.False(weakReference.IsAlive);
}

This does not require

<TieredCompilation>false</TieredCompilation>
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!