linuxmemory.net-coreswapfile

Dotnet Core Will Not Use Swap


I've written a simple dotnet app that allocates memory. It uses up all the physical memory on the machine and then crashes with an OutOfMemoryException. However my system has a swap file and it is never used by dotnet. Other applications use swap just fine. I have played with the swappiness (60, 100, 1) but this had no effect.

My understanding is that a process on Linux can consume all the physical memory it wants and if there is no memory left that memory will be written to the swap file/partition. Only when the swap and physical memory are both full should an application crash with an OOM. This is what other applications do but not dotnet applications.

I have tried dotnet core 3.1 and 5.0, the OS used was Ubuntu 20.04.

EDIT: my test code:

namespace TestProject
{
    class Program
    {
        static List<byte[]> l = new List<byte[]>();

        static void Main(string[] args)
        {
            while (true)
            {
                var b = new byte[100 * 1000 * 1024];
                l.Add(b);
            }
        }
    }
}

Solution

  • OK after some trial and error I understand (more or less) what's happening. In the code above the array isn't fully allocated unless it's elements are 'touched'. By that I mean that the memory consumed isn't what I would expect it to be unless I do something like Array.Fill<byte>(b, 0) before storing the array in the static list. While I didn't know of this behavior it seems like some delayed allocation on the part of dotnet which does make sense in order to keep memory use down (ie don't actually allocate until you are going to use the array). If I use the Array.Fill then the memory climes much quicker and eventually does get paged out to swap.

    So why did I get an OOM before? I believe the answer was that I was hitting the 2GB object size for the static list. This was a limit that I wasn't aware of but in dotnet no single object can go over 2GB. With the code above I believe enough memory was used up in the list object (the inner array, pointers to all the elements etc) that it hit that 2GB limit and cause the OOM.

    Thanks everyone who read this and provided feedback.