繁体   English   中英

编程c#:Parallel.Foreach内存消耗管理

[英]Programming c#: Parallel.Foreach Memory Consumption Management

我想使用Parallel.Foreach机制来确保CPU密集型任务的CPU充分利用。 我一次从数据库中查询大量对象(每次迭代中只有一个对象,每个对象相当小),然后对该对象执行大量基于CPU的操作,然后将其保存回去。到数据库。

我在数据模型侧使用实体框架,并根据查询的对象数量,为每次迭代创建一个新的上下文(这是为了限制内存消耗):

    foreach (var id in idlist)
    {
        using (var ctx = new Context())
        {
            var model = ctx.Models.First(x => x.Id == id);
            await model.GlobalRefresh(true); //CPU heavy operation.
            await model.SaveAsync(); //Additional CPU heavy operation.
            ctx.SaveChanges(); //Save the changes
        } //Dispose of the model and the context, to limit memory consumption
    }

这在同步实现中效果很好,因为在每次迭代之后,都会处理从数据库查询的模型和实体框架上下文。 因此,在此过程中我的内存消耗几乎是恒定的,这非常好。 如果不以这种方式创建上下文,则会很快耗尽内存(500多个对象)。

当我按如下所示并行进行上述设置时,我的内存消耗飞速增长,因为似乎每次迭代的上下文在下一次迭代继续之前就没有释放(并且我确实看到了预期的明显更高的CPU利用率):

        Parallel.ForEach(idlist, async (id) =>
        {
            using (var ctx = new Context())
            {
                var model = ctx.Models.First(x => x.Id == id);
                await model.GlobalRefresh(true);
                await model.SaveAsync();
                ctx.SaveChanges();
            }
        });

从内存的角度来看,这并不一定是问题,只要所有模型对象都不会一次加载到内存中(这实际上是并行循环的整个要点,一次要加载多个)。 但是,是否有某种方法可以更好地管理此过程,例如在内存消耗达到75%时不创建其他任务,以避免内存不足异常?

TL; DR:可以在下次操作之前使用MemoryFailPoint检查是否有足够的内存。 Microsoft Docs 在这里有一个很好的例子。

我最近有一个类似的问题。 在检查较旧应用程序的日志时,我注意到一些“内存不足异常”。 事实证明,开发人员引入了一些并行编程,以使应用程序更快。 因此,也许该应用程序运行速度更快,但现在消耗的内存速度更快,并且达到了32位应用程序内存限制 (约为2GB),然后出现了这些内存不足异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM