linux - Dotnet Core 将不会使用交换

标签 linux memory .net-core swapfile

我编写了一个简单的 dotnet 应用程序来分配内存。它耗尽了机器上的所有物理内存,然后因 OutOfMemoryException 崩溃。然而,我的系统有一个交换文件,并且 dotnet 从未使用过它。其他应用程序使用交换就可以了。我已经使用了 swappiness (60, 100, 1),但这没有效果。

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

我尝试过dotnet core 3.1和5.0,使用的操作系统是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);
            }
        }
    }
}

最佳答案

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

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

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

关于linux - Dotnet Core 将不会使用交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65818325/

相关文章:

c - 使用 syslog.h 将自定义时间戳写入 syslog

linux - 我有一年中的某一天。如何在shell脚本中获取日期

npm - DotNet Core 2.0 WebDeploy 对 npm build 的调用在 Publish 上不起作用

Linux 1604 : kestrel service can't find dotnet installation

linux - 使用 setuid 的可执行文件找不到共享库

java - 垃圾收集器如何快速知道哪些对象不再有对它们的引用?

python - 合并 Pandas 数据帧使用太多内存

swift - 如何从内存中清除 SKSpriteNode?

visual-studio - 在 Visual Studio 2015 中打开 Visual Studio 2017 项目

c++ - 使用 C++ 在 Linux 中停止并重新开始运行进程