您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

如果使用可枚举的大对象,Parallel.ForEach可能会导致“内存不足”异常

如果使用可枚举的大对象,Parallel.ForEach可能会导致“内存不足”异常

Parallel.ForEach 认选项 。当任务受cpu限制时,一切都将正常运行。如果您具有四核并且没有其他进程在运行,则Parallel.ForEach使用所有四个处理器。如果您具有四核,并且计算机上的某些其他进程正在使用一个完整的cpu,则Parallel.ForEach大约使用三个处理器。

但是,如果任务不受cpu限制,则Parallel.ForEach继续启动任务,努力使所有cpu保持忙碌状态。但是,无论并行执行多少任务,总是有更多未使用的cpu功能,因此它会继续创建任务。

如何判断您的任务是否受cpu限制?希望只是通过检查。如果要分解素数,这是显而易见的。但是其他情况并不那么明显。判断任务是否受cpu限制的经验方法是限制最大并行度,ParallelOptions.MaximumDegreeOfParallelism并观察程序的行为。如果您的任务是cpu密集型的,那么您应该在四核系统上看到这样的模式:

如果行为如此,则可以使用Parallel.ForEach选项并获得良好的效果。线性的cpu利用率意味着良好的任务调度。

但是,如果我在Intel i7上运行示例应用程序,则无论我设置的最大并行度如何,我都会获得约20%的cpu利用率。为什么是这样?由于分配了太多内存,垃圾回收器阻塞了线程。应用程序是资源绑定的,资源是内存。

同样,对数据库服务器执行长时间运行查询的I / O绑定任务也永远无法有效利用本地计算机上可用的所有cpu资源。并且在这种情况下,任务计划程序无法“知道何时停止”开始新任务。

如果您的任务不受cpu限制,或者cpu利用率不能以最大并行度线性扩展,则应建议Parallel.ForEach不要一次启动太多任务。最简单的方法是指定一个数字,该数字允许对重叠的I / O绑定任务进行某种并行处理,但又不能过多,以至于使本地计算机对资源的需求不堪重负,或者使任何远程服务器负担过多。反复试验才能获得最佳结果:

static void Main(string[] args)
{
    Parallel.ForEach(CreateData(),
        new ParallelOptions { MaxDegreeOfParallelism = 4 },
        (data) =>
            {
                data[0] = 1;
            });
}
其他 2022/1/1 18:21:46 有535人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶