【问题标题】:Out of Memory Exception in Parallel.ForEachParallel.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 个字符串。

如何处理?

【问题讨论】:

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

标签: c# garbage-collection task-parallel-library


【解决方案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);
    });

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

【讨论】:

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

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

【讨论】:

  • 不,实际上我是在完成了几个任务后得到了异常。
猜你喜欢
  • 1970-01-01
  • 2010-10-05
  • 1970-01-01
相关资源
最近更新 更多