Parallel.ForEach 内存不足异常

Posted

技术标签:

【中文标题】Parallel.ForEach 内存不足异常【英文标题】:Out of Memory Exception in Parallel.ForEach 【发布时间】:2014-05-18 18:13:43 【问题描述】:

我正在使用 Parallel.ForEach 完成我的工作,但出现“内存不足异常”。

Parallel.ForEach(flist, (item) =>

    string f1 = item.Split('|')[0];
    string f2 = item.Split('|')[1];
    a = File.ReadAllText(f1);
    b = File.ReadAllText(f2); 
    Consume(a, b);
);

flist 的大小是 351,ab 是字符串,每个都有 20kb 大小。在某个时间,系统内存爆炸了。

使用返回一个字符串列表,通常每次迭代大约 1000 个字符串。

如何处理?

【问题讨论】:

消费是做什么的?是否占用大量内存? 你查看过这篇文章了吗:***.com/questions/6977218/… 设置最大并行度有帮助吗? 您很有可能同时创建 351 个线程。每个都有一个 1MB 的堆栈,加上文件文本和字符串/列表等使用的内存。它可能会耗尽内存并不是不可想象的。尝试将ParallelOptions.MaxDegreeOfParallelism 设置为 4,看看是否有帮助。 --@Baldrick,我不确定如何在代码中添加 ParallelOptions.MaxDegreeOfParallelism。你能修改我的代码吗? 【参考方案1】:

尝试替换:

  Parallel.ForEach(flist, (item) =>
    
        string f1 = item.Split('|')[0];
        string f2 = item.Split('|')[1];
        a = File.ReadAllText(f1);
        b = File.ReadAllText(f2); 
        Consume(a, b);
    );

与:

    Parallel.ForEach(flist, 
    new ParallelOptions  MaxDegreeOfParallelism = 4 ,
    (item) =>
    
        string f1 = item.Split('|')[0];
        string f2 = item.Split('|')[1];
        a = File.ReadAllText(f1);
        b = File.ReadAllText(f2); 
        Consume(a, b);
    );

这将防止创建过多的线程。然后,您可以随时尝试更高的数字,看看性能是否有所提高。

【讨论】:

我在使用代码后遇到另一个错误,***Exception。“由于 ***Exception 而终止进程”。 你在某处有递归吗? 是的,Consume 本身是深度递归的。【参考方案2】:

每个循环两次将整个文件读入单个字符串。如果文件很大,这很可能是问题的根源。

【讨论】:

不,实际上我是在完成了几个任务后得到了异常。

以上是关于Parallel.ForEach 内存不足异常的主要内容,如果未能解决你的问题,请参考以下文章

保留内存是不是会导致内存不足异常

Flink on Yarn 提交任务由于内存不足产生的异常调试

内存不足异常 - 非托管内存

为啥我的 C# 应用程序中出现内存不足异常?

大位图内存不足异常

内存不足异常