Dotnet Core 不会使用交换

问题描述

我编写了一个简单的 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);
            }
        }
    }
}

解决方法

好的,经过一些反复试验,我明白(或多或少)发生了什么。在上面的代码中,数组没有完全分配,除非它的元素被“触及”。我的意思是消耗的内存不是我所期望的,除非我在将数组存储在静态列表中之前执行类似 Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) Const srcFirst As String = "C4" Const dstFirst As String = "C4" Dim srg As Range: Set srg = defineColumnRange(Range(srcFirst)) If srg Is Nothing Then With Sheet2.Range(dstFirst) .Resize(.Worksheet.Rows.Count - .Row + 1).ClearContents End With Exit Sub End If Dim rg As Range: Set rg = Intersect(srg,Target) If rg Is Nothing Then Exit Sub Dim dCel As Range: Set dCel = Sheet2.Range(dstFirst) On Error GoTo clearError Application.EnableEvents = False copySortedUniqueColumn srg,dCel SafeExit: Application.EnableEvents = True Exit Sub clearError: Resume SafeExit End Sub 的操作。虽然我不知道这种行为,但似乎 dotnet 部分的一些延迟分配是有意义的,以减少内存使用(即在您要使用数组之前不实际分配)。如果我使用 Array.Fill<byte>(b,0),那么内存会加快很多,最终确实会被调出以进行交换。

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

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...