C#循环迭代长时间进程时性能下降

4

概览
我在遍历一个计算器类时面临性能下降的问题。开始时,每次迭代需要大约3分钟,并且随着迭代次数的增加,时间会越来越长(每个进程需要30分钟以上)。我必须停止程序/重新执行,以便回到正常状态(每个进程需要3分钟)。

我的做法
我有一个科学应用程序,它在一个过程中测试一组参数。 例如,我有N个场景(即参数组合),在实验集上进行测试,该集合包括一个计算器类,该类将参数输入其中,在T个可能的XP条件下进行处理,并将输出存储在ORM对象中,每次迭代后都会发送到数据库。换句话说,每个N个参数组合都会通过计算器传递T次。

Parameter combination : Params Set 1, Params Set 2, ...., Params Set  N
Experimental Set      : XP Set 1    , XP Set 2    , ...., XP Set T

我有NxT种组合,其中N和T各约为256,总计65000+次迭代。

实现方式
我有一个GUI来设置参数集,并启动后台工作程序(每个参数组合一个)。每个后台工作程序加载T个XP设置中的第一个,执行当前参数集,然后移动到下一个XP设置,依此类推。每个单独的迭代之后计算器会生成报告,并触发事件将.NET Linq/SQL ORM对象(AgileFX)填充并存储到SQL Server数据库中。

问题
该过程在前30分钟内运行良好,然后慢慢开始漂移,每个迭代需要越来越长的时间(听起来像是内存溢出等问题...)

提示
奇怪的是,一位实验者非常明确地注意到处理时间呈线性增长:前一个处理时间再加3分钟。这归结为一个等差数列(Tn+1 = Tn + 3mn)。我有一个12核Intel和24GB RAM。


确定你的.NET应用程序是否存在内存泄漏:http://mitch-wheat.blogspot.com/2010/11/determine-if-your-net-application-has.html - Mitch Wheat
你在这里问什么?我只看到一堆数学/文本,没有代码或问题。 - RPM1984
1
@RPM:问题显而易见,已经在标题和概述中提到了:问题在于连续执行应该只需要3分钟的进程却需要越来越长的时间。所有编程问题并非直接与代码相关,而是涉及设计和解决方案的轨迹。 - Mehdi LAMRANI
@Mitch:好提示,我会看一下的。 - Mehdi LAMRANI
2个回答

1
一个快速的建议,你可以通过记忆化来解决你的问题,避免重新计算已知结果。
另外,请记住,如果垃圾收集器在某种方式下找到对象的引用,它将无法进行垃圾回收!

我无法避免计算,因为每个组合场景都是独特的。垃圾回收应该非常无缝,我不知道如何“强制”终止对某些对象的引用。 - Mehdi LAMRANI
你需要将所有对它的引用置空,例如:对象A = null; - user523650

1

我觉得我已经找到了问题的一部分,但它没有完全解决问题:

对象通过由监听器注册的委托发送到ORM,所以每个计算线程在结束后仍然在内存中“存在”。 就像一个同事说的:“即使你搬走了,如果我仍然在我的寄存器中有你的地址,对我来说你仍然住在附近。”

顺便说一句,VS2010中的性能向导非常有效。非常深入和准确地监控整体内存性能,非常有用。

编辑:问题已解决
负责触发后台工作线程的类在跟踪对象中保留了一些数据,这些数据不断增长并且从未刷新,变得越来越大。通过紧密追踪VS 2010性能向导中每个对象的内存使用情况,我注意到了这一点。
我建议清楚地了解对象的生命周期和内存使用情况,尤其是当应用程序庞大而复杂时,这可能会很困难。


这就是为什么当您完成对事件的监听时,应注销该事件,并在对象完成时将其内部事件委托设置为 null 的原因。 - DarrellNorton
1
另外,由于您正在使用.NET 4,请查看任务并行库:http://msdn.microsoft.com/en-us/library/dd460717.aspx - DarrellNorton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接