【问题标题】:Parallel Foreach Memory Issue并行 Foreach 内存问题
【发布时间】:2011-05-11 08:32:41
【问题描述】:

我在 FileInfoCollection 中有一个文件集合(3000 个文件)。我想通过应用一些独立的逻辑(可以并行执行)来处理所有文件。

 FileInfo[] fileInfoCollection = directory.GetFiles();
 Parallel.ForEach(fileInfoCollection, ProcessWorkerItem);

但在处理了大约 700 个文件后,我遇到了内存不足错误。我之前使用过线程池,但它给出了同样的错误。 如果我尝试在没有线程(并行处理)的情况下执行,它工作正常。

在“ProcessWorkerItem”中,我正在运行基于文件字符串数据的算法。此外,我使用 log4net 进行日志记录,并且在这种方法中与 SQL 服务器有很多通信。

这里有一些信息,文件大小:1-2 KB XML 文件。我阅读了这些文件,该过程取决于文件的内容。它正在识别字符串中的一些关键字并生成另一种 XML 格式。关键字在 SQL server 数据库中(将近 2000 个字)。

【问题讨论】:

  • 如果您发布“ProcessWorkerItem”会有所帮助。
  • 文件 IO 是否适合并发处理?
  • 另外,IIRC 和 OutOfMemoryException 表示缺少连续页内存;你可能会通过组织你的方法以在更多的小块中使用内存而侥幸。
  • @Robert ,'ProcessWorkerItem' 不能被描述为一个单一的方法,因为它也调用了几个方法。但我可以给个描述
  • @phil ,我不明白如何“在更多的小块中使用内存”

标签: .net multithreading plinq


【解决方案1】:

那么,ProcessWorkerItem 是做什么的?您可以更改它以使用更少的内存(例如,流式传输数据而不是一次全部加载)或者您可能希望使用this overloadParallelOptions.MaxDegreeOfParallelism 明确限制并行度。基本上你想避免一次处理所有 3000 个文件 :) IIRC,如果你的任务似乎是 IO 绑定的,Parallel Extensions 会“注意到”,并允许一次执行超过正常数量 - 这不是真正的你想在这里,因为你也受内存限制。

【讨论】:

  • 你能给我一些分数来决定 MaxDegreeOfParallelism 吗?如何确定最佳价值?
  • @Jayantha:这完全取决于您的 ProcessWorkerItem 方法在做什么。您认为一次可以合理处理多少个文件?
  • 这些文件的逻辑处理是相互独立的,所以我可以处理任意数量的文件:)。但硬件限制。我有 4 GB RAM 的核心 i5 处理器。处理单个文件平均需要 1 秒
  • @Jayantha:但是你仍然没有解释你对这些文件做了什么,或者它们有多大,或者为什么你会耗尽内存。如果您正在执行每个文件需要 1GB 的操作,那么您一次将无法处理超过两个或三个......而如果您正在做一些微不足道的事情,您可能会处理数百个。
  • @Jayantha:好吧,我首先要摆脱并行性。你能毫无问题地连续运行整个事情吗?如果是这样,听起来你可能只需要降低并行度。如果没有,请使用分析器并检查哪些对象不应该挂在周围。
【解决方案2】:

如果您尝试对大文件进行并行操作,那么您可能会耗尽可用内存。

也许考虑尝试Rx 扩展并使用它的 Throttle 方法来控制/组合您的处理?

【讨论】:

  • 实际上这些文件并不太大,平均 1-2 KB 大小的 XML 文件
【解决方案3】:

我发现了引发内存泄漏的错误,我将工作单元模式与实体框架一起使用。在工作单元中,我将上下文保存在一个哈希表中,其中线程名称作为哈希键。当我使用线程时,哈希表会不断增长,并且会导致内存泄漏。 所以我在工作单元中添加了额外的方法,以便在完成线程任务后从哈希表中删除元素。

public static void DisposeUnitOfWork()
        {
            IUnitOfWork unitOfWork = GetUnitOfWork();

            if (unitOfWork != null)
            {
                unitOfWork.Dispose();
                hashTable.Remove(Thread.CurrentThread.Name);


            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 2015-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多