【问题标题】:C# Threading Parallel.ForEach and DirectoryInfo Out of Memory ExceptionC# 线程 Parallel.ForEach 和 DirectoryInfo 内存不足异常
【发布时间】:2012-03-30 13:17:19
【问题描述】:

我有一个非常简单的 Parallel.ForEach 调用下面的代码:

var maxDegree = new ParallelOptions{MaxDegreeOfParallelism = 5};
Parallel.ForEach(PList,maxDegree,fl =>
            {
                ProjectDirectoryProcessing pjp = new ProjectDirectoryProcessing();
                pjp.ProjectProcessor(fl);
                Console.ReadLine();
            }
        );

public class ProjectDirectoryProcessing
{

    public void ProjectProcessor(string rootDirectory)
    {
           DirectoryInfo Dinfo = new DirectoryInfo(rootDirectory);
            DirectoryInfo[] directories = Dinfo.GetDirectories("*.*", SearchOption.AllDirectories);
            FileInfo[] finfo = Dinfo.GetFiles("*.*", SearchOption.AllDirectories);
            foreach (FileInfo f in finfo)
            {
                FileSize = FileSize + f.Length;
            }
            FileCount = finfo.Length;
            DirectoryCount = directories.Length;
    }
}

问题是我的内存不足,我在 Parallel.ForEach 中的 pjp.ProjectProcessor 之后考虑了 GC.Collect() 但我不确定这是否可行。这些目录非常大,我不肯定清理这些目录会有所帮助。有什么好的方法来处理这个问题?

【问题讨论】:

  • 这取决于您需要对文件执行的操作。 Directory.EnumerateFiles 可能会产生巨大的影响。
  • 查看编辑,我只是​​在计算目录的大小和文件数,而 Directory.EnumerateFiles 会导致巨大的性能问题
  • 您的应用程序到底应该做什么?不能切换到生产者-消费者模型,一个一个地加载文件夹吗?
  • @Tudor 我实际上尝试了这种方法并且性能非常好,例如时间从上面的 52 分钟变成了大约 4 小时。
  • @Mike:你是使用一个线程来引导目录还是多个并行?

标签: c# multithreading directoryinfo


【解决方案1】:

手动调用 GC 无济于事,因为应该在抛出 OutOfMemoryException 之前自动调用 GC。 一种简单的解决方案是将应用程序编译为 x64。这是一个选项吗?

【讨论】:

  • 目前不行,我可以要求一个测试盒并试一试,会有那么大的帮助吗?
  • 当然。我一直在处理无法在 x64 上完美运行的 x32 地址空间的大型应用程序。你不是真的用完了内存,而是地址空间。
  • 这不是4gb,4gb吗?不管是 32 位还是 64 位,我认为 64 位的意义在于访问更大的内存使用率
  • 比这更复杂。每个进程有 2Gb 地址空间。前段时间我有一些记忆过程。检查这个,真的很好解释:stackoverflow.com/questions/9610552/…
猜你喜欢
  • 2014-05-18
  • 1970-01-01
  • 2012-01-23
  • 2016-07-27
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
相关资源
最近更新 更多