Search code examples
c#memory-leaksgarbage-collection

c# AddMemoryPressure memory leak


I wrote the test. And run it on net5 and net472. dotMemory shows growth in unmanaged Memory.

var size = 1920 * 1080 * 3 / 2;

for (int i = 0; i < int.MaxValue; i++)
{
    GC.AddMemoryPressure(size);
    GC.RemoveMemoryPressure(size);
    Thread.Sleep(1);
}

Is it a memory leak? Why is dotMemory showing this?

net472

net5


Solution

  • dotMemory derives Unmanaged memory from Total used minus all managed memory. Total used is based on RSS (resident set size):

    Memory Category Usage
    Total used 14.2 MB
    Unmanaged memory 13.6 MB
    Heap generation 0 24.0 B
    Heap generation 1 24.0 B
    Heap generation 2 335.1 KB
    LOH and POH 312.1 KB
    USER             PID  %CPU %MEM       VSZ    RSS   TT  STAT STARTED      TIME COMMAND
    user           28318  15.0  0.1 410585360  14572 s002  S+   12:21AM  23:02.94 test
    

    Total used = RSS/1024 = 14572/1024 = 14.23 MB

    Unmanaged memory = Total used - Heap* - LOH and POH = 14.2-(24*2/1024/1024+335.1/1024+312.1/1024) = 13.56 MB

    So, any native allocation/deallocation can affect Unmanaged memory. In the context of your sample, the most likely cause of unexpected RSS volatility/growth is the dotMemory agent library injected into the target process. A straightforward way to narrow down the source is to run the sample with and without dotMemory. I used .NET Core (7.0.305) for a 25 minute comparison based on the sample you provided:

    Without dotMemory

    withoutdotmemory

    With dotMemory (libJetBrains.Profiler.Core.dylib loaded)

    withdotmemory

    ![withdotmemory2

    In the latter case, RSS is higher and considerably more volatile than without the agent. For this sample, the growing unmanaged memory that you observed is most likely caused by the agent.

    In my reproduction scenario, where unmanaged memory does not increase throughout the 25 minutes, I used dotMemory 231.9161.46 with JetBrains Rider. However, dotMemory had memory leaks in the past:

    https://resharper-support.jetbrains.com/hc/en-us/community/posts/207774725-dotMemory-and-unmanaged-memory

    https://youtrack.jetbrains.com/issue/DMRY-3915

    If you're not using the most recent version, update your installation to rule out that you're still affected by that or related issues. If RSS does not increase without the agent, the agent is to blame. If, however, it does increase without the agent, the runtime or another component that is unique to your .NET installation is causing the issue - highly unlikely.

    Based on the information you provided and my observations, my conclusion is that your dotMemory version causes the unmanaged memory growth. If not and further investigation is required, I recommend using the valgrind tool massif to visualize the heap growth. Depending on the allocators involved and available symbols, doing so can range from being straightforward (malloc used, symbols are available) to a dead end (custom allocators and missing symbols prevent fine-grained analysis).