Description
Starting from 8.0.17 runtime version, GC does not return unmanaged memory to the OS on forced full GC.
Suspected change is #115023
Related: #108081
Reproduction Steps
-
Make sure you have both 8.0.16 and 8.0.17 runtimes installed, 8.0.410 and 8.0.411 respective versions of SDK
-
Program.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RollForward>Disable</RollForward>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>
</Project>
- Program.cs:
using System.Diagnostics;
using System.Runtime.CompilerServices;
Console.WriteLine(Environment.Version);
for (int i = 0; i < 10; i++)
{
_ = Allocate();
}
Console.WriteLine($"Private memory before GC: {GetPrivateMemoryMb()} MB");
TriggerGc(); // No matter how many times you call this, process private memory stays the same on 8.0.17
Console.WriteLine($"Private memory after GC: {GetPrivateMemoryMb()} MB");
[MethodImpl(MethodImplOptions.NoInlining)]
int Allocate()
{
var data = new byte[1_000_000_000];
return data.Length;
}
void TriggerGc()
{
GC.Collect(generation: 2, GCCollectionMode.Forced, blocking: true, compacting: true);
GC.WaitForPendingFinalizers();
Thread.Sleep(1000);
}
double GetPrivateMemoryMb()
{
using var process = Process.GetCurrentProcess();
var mb = process.PrivateMemorySize64 / 1024.0 / 1024.0;
return Math.Round(mb, 2);
}
-
Run dotnet clean -c Release && dotnet run -c Release -p:RuntimeFrameworkVersion='8.0.16'
-
Run dotnet clean -c Release && dotnet run -c Release -p:RuntimeFrameworkVersion='8.0.17'
Expected behavior
Behavior should not change between patch versions of runtime, and preferably, GC should return memory to the OS on forced compacting GC.
Actual behavior
8.0.16
Private memory before GC: 9614.54 MB
Private memory after GC: 60.44 MB
8.0.17
Private memory before GC: 9614.56 MB
Private memory after GC: 9615.96 MB
Regression?
Yes. Regression from 8.0.16
Known Workarounds
- Use 8.0.16 runtime version
Configuration
OS: Windows 11
Architecture: x64
Other information
No response
Description
Starting from 8.0.17 runtime version, GC does not return unmanaged memory to the OS on forced full GC.
Suspected change is #115023
Related: #108081
Reproduction Steps
Make sure you have both 8.0.16 and 8.0.17 runtimes installed, 8.0.410 and 8.0.411 respective versions of SDK
Program.csproj:
Run
dotnet clean -c Release && dotnet run -c Release -p:RuntimeFrameworkVersion='8.0.16'Run
dotnet clean -c Release && dotnet run -c Release -p:RuntimeFrameworkVersion='8.0.17'Expected behavior
Behavior should not change between patch versions of runtime, and preferably, GC should return memory to the OS on forced compacting GC.
Actual behavior
Regression?
Yes. Regression from 8.0.16
Known Workarounds
Configuration
OS: Windows 11
Architecture: x64
Other information
No response