Dotnet Core 不会使用 Swap

Dotnet Core Will Not Use Swap

我编写了一个简单的 dotnet 应用程序来分配内存。它用完了机器上的所有物理内存,然后崩溃并显示 OutOfMemoryException。但是我的系统有一个交换文件,dotnet 从未使用过它。其他应用程序使用交换就好了。我玩过 swappiness (60, 100, 1) 但这没有效果。

我的理解是 Linux 上的进程可以消耗它想要的所有物理内存,如果没有剩余内存,内存将被写入交换区 file/partition。只有当交换内存和物理内存都已满时,应用程序才会因 OOM 而崩溃。这是其他应用程序所做的,但 dotnet 个应用程序不这样做。

我试过 dotnet core 3.1 和 5.0,使用的 OS 是 Ubuntu 20.04.

编辑:我的测试代码:

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);
            }
        }
    }
}

好的,经过一些尝试和错误,我明白(或多或少)发生了什么。在上面的代码中,数组没有完全分配,除非它的元素是 'touched'。我的意思是消耗的内存不是我期望的,除非我在将数组存储在静态列表中之前执行类似 Array.Fill<byte>(b, 0) 的操作。虽然我不知道这种行为,但似乎在 dotnet 方面进行了一些延迟分配,这对于减少内存使用确实有意义(即在您要使用数组之前不实际分配)。如果我使用 Array.Fill,那么内存占用会更快,最终会被调出进行交换。

那我之前为什么会出现OOM呢?我相信答案是我达到了静态列表的 2GB 对象大小。这是一个我不知道的限制,但在 dotnet 中没有单个对象可以超过 2GB。使用上面的代码,我相信列表对象(内部数组、指向所有元素的指针等)中已经用完了足够的内存,它达到了 2GB 的限制并导致 OOM。

感谢所有阅读本文并提供反馈的人。