Dotnet Core将不使用Swap



我写了一个简单的dotnet应用程序分配内存。它耗尽了机器上的所有物理内存,然后在OutOfMemoryException中崩溃。然而,我的系统有一个交换文件,它从来没有被dotnet使用。其他应用程序也可以很好地使用swap。我试了一下swappiness(60,100,1),但是没有效果。

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

我尝试了dotnet core 3.1和5.0,使用的操作系统是Ubuntu 20.04。

编辑: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);
}
}
}
}

好的,经过一些尝试和错误,我明白(或多或少)发生了什么。在上面的代码中,数组没有完全分配,除非它的元素被"触摸"。我的意思是,所消耗的内存不是我所期望的,除非我在将数组存储在静态列表中之前执行Array.Fill<byte>(b, 0)之类的操作。虽然我不知道这种行为,它似乎是一些延迟分配的部分,这是有意义的,以保持内存使用下降(即不实际分配,直到你要使用数组)。如果我使用Array.Fill,那么内存会更快地增加,最终会被分页出来进行交换。

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

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

相关内容

  • 没有找到相关文章

最新更新