Skip to content

AppDomain.MonitoringSurvivedMemorySize incorrect in .NET 5.0 #45446

Closed
@timcassell

Description

@timcassell

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions