我编写了一段测试代码,使用AsParallel来同时读取大文件.它会导致内存泄漏.GC似乎没有像预期的那样回收未使用的对象.请参阅代码片段.

        static void Main(string[] args)
        {
            int[] array = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

            //foreach (var element in array) // No leaks
            //{
            //    ReadBigFile();
            //}

            array.AsParallel().ForAll(l => ReadBigFile()); // Memory leak

            Console.ReadLine();
        }

        private static void ReadBigFile()
        {
            List<byte[]> lst = new List<byte[]>();
            var file = "<BigFilePath>"; // 600 Mb
            lst.Add(File.ReadAllBytes(file));
        }

我try 了同步和并行两种方式.同步foreach运行正常,因为没有内存泄漏.但当我使用AsParallel同时读取文件时,内存泄漏会发生,因为它占用了6GB的内存,而且永远不会返回.

请帮助确定根本原因是什么?如果我想同时完成同样的任务,写东西的人要做什么?非常感谢.

PS:这个问题发生在dotnet框架(4.6.1)和dotnet核心(6.0)中.

推荐答案

@外交不是战争

如果按顺序执行,那么就不会引用上一个循环中的对象,这使得它可以移动到下一代,并最终进行垃圾收集.

然后我将代码修改为

        int[] array = new[] { 1, 2 };
        for (int i = 0; i < 5; i++)
        {
            array.AsParallel().ForAll(l => ReadBigFile()); 
        }

不,我可以看到内存分配只有1.1GB,这应该是最后一轮循环所需的内存大小.所以我想现在我确信,这只是GC的时间问题,而不是真正的内存泄漏.非常感谢@CompellacyNotwar!

Csharp相关问答推荐

C#使用属性和值将JSON转换为XML

如何告诉自己创建的NuGet包在应用程序中发生了变化?

`Task`只有在C#中等待时才会运行吗?

MAUI查询参数单一字符串项将不起作用

默认情况下,.NET通用主机(Host.CreateDefaultBuilder)中是否包含UseConsoleLifetime?

mocking对象的引发事件并作为用于调用方法的参数对象传递到那里

Rider将.NET安装在哪里

CS1660无法将lambda表达式转换为类型INavigationBase,因为它不是委托类型

如何捕获对ASP.NET核心应用程序的所有请求并将其发送到一个页面

当索引和外键是不同的数据类型时,如何设置导航属性?

EFR32BG22 BLE在SPP模式下与PC(Windows 10)不连接

为什么C#/MSBuild会自发地为不同的项目使用不同的输出路径?

匿名类型的AbstractValidator

此异步方法在重写方法中缺少等待运算符警告

将C#类导入到PowerShell

将字符串类型日期输入(yyyy-mm-ddthh:mm:ss)转换为MM/dd/yyyy格式

如何在更新数据库实体时忽略特定字段?

单位中快照的倾斜方向

如何在C#中用Serilog记录类路径、方法名和行编号

Windows Forms(.NET)中文件对话框中的深色模式差异