我有一个作业处理器,它需要并行处理约 300 个作业(作业最多可能需要 5 分钟才能完成,但它们通常是网络绑定的)。
我遇到的问题是,工作往往以特定类型的形式出现。为简单起见,假设有六种工作类型,JobA
通过JobF
.
JobA
-JobE
是网络绑定的,可以很高兴地让 300 个一起运行而不会对系统造成任何负担(实际上,我已经设法在测试中让超过 1,500 个并排运行)。JobF
(一种新的作业类型)也是网络绑定的,但它需要大量内存并且实际上使用 GDI 功能。
我确保我仔细处理所有带有using
s 的 GDI 对象,并且根据分析器,我没有泄漏任何东西。只是JobF
并行运行 300 比 .NET 愿意给我的内存更多。
处理这个问题的最佳实践方法是什么?我的第一个想法是确定我有多少内存开销,并在我接近极限(至少是JobF
作业)时限制生成新作业。我无法实现这一点,因为我找不到任何方法来可靠地确定框架愿意在内存方面分配给我什么。我还必须猜测一个看起来有点古怪的工作使用的最大内存。
我的下一个计划是在我收到 OOM 时简单地限制并重新安排失败的作业。不幸的是,OOM 可能发生在任何地方,而不仅仅是在有问题的作业内部。事实上,最常见的地方是管理作业的主工作线程。就目前情况而言,这会导致进程正常关闭(如果可能)、重新启动并尝试恢复。虽然这很有效,但它既讨厌又浪费时间和资源——比仅仅回收那个特定的工作要糟糕得多。
是否有处理这种情况的标准方法(添加更多内存是一种选择并且会完成,但应用程序应该正确处理这种情况,而不仅仅是炸弹)?