Closed
Description
While trying to add a new feature to BDN to measure survived memory (dotnet/BenchmarkDotNet#1596), I found that .NET Core 3.1 and .NET 5.0 were reporting unexpected values. I made a separate application to test whether the measurements I'm making are even accurate separate from all other BDN code. I found that it seems to be accurate in .NET Core 3.1, but it's off in .NET 5.0.
Console prints:
Survived bytes: 0
Survived bytes: 24
Survived bytes: 24
With this code:
using System;
using System.Runtime.CompilerServices;
namespace MemoryTest
{
class Program
{
static int n;
static void Main(string[] args)
{
n = 1_000_000;
Measure(); // Run once for GC monitor to make its allocations.
Console.WriteLine($"Survived bytes: {Measure()}");
Console.WriteLine($"Survived bytes: {Measure()}");
Console.WriteLine($"Survived bytes: {Measure()}");
}
static long Measure()
{
long beforeBytes = GetTotalBytes();
NonAllocatingMethod();
long afterBytes = GetTotalBytes();
return afterBytes - beforeBytes;
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void NonAllocatingMethod()
{
for (int i = 0; i < n; i++) { }
}
static long GetTotalBytes()
{
AppDomain.MonitoringIsEnabled = true;
// Enforce GC.Collect here to make sure we get accurate results.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
return AppDomain.CurrentDomain.MonitoringSurvivedMemorySize;
}
}
}
[Edit] This was ran with Visual Studio 16.8.2 on Windows 7 SP1 on AMD Phenom II x6.
Also, the results above were from running in DEBUG mode directly in Visual Studio. After building in RELEASE configuration and running it separately, I got these results (different, but still wrong):
Survived bytes: 0
Survived bytes: 24
Survived bytes: 0