2010-05-20 39 views
2

我有用VB.NET和目标Framework 1.1编写的单线程窗体窗体应用程序。该软件通过串行接口与外部电路板进行通信,主要由一个状态机组成,它运行一些测试,由一个带有定时器和50ms间隔的循环驱动。如何解决VB.NET 1.1应用程序的性能衰减问题?

用户界面上的反馈是通过测试过程中产生的一些自定义事件完成的。

引起我疯狂的问题是性能会随着时间的推移稍微下降,特别是在1200/1300测试操作之后。占用的内存不会随着时间增加,它只是CPU似乎对这个问题感兴趣。

奇怪的是,针对框架2.0和使用相同的代码,我没有这个问题。

我知道这很难不看代码,但你有什么建议我可以如何解决这个问题?

编辑:经过几次密集的工作后,我真的迷路了,应用程序开始放慢速度。选中的行与其进程相关,如果有帮助的话。

EDIT2:使用Windows任务管理器我检测到手柄计数器在每个操作结束时增加1。我不知道是不是原因,但是当手柄计数器达到大约1500个手柄时,应用程序开始减速。我检查了所有必要的RemoveHandler是在每次操作后调用的。任何想法?

EDIT3:我发现处理是由C++库我们使用与串行设备传送所产生的问题。它然后发生在.NET 1.1和.NET 2.0中。不同之处在于,如果目标.NET 1.1应用程序减速/冻结而不是.NET 2.0,则达到30000个以上的句柄而不会失去性能。现在我不知道这个问题是否真的是由这个丢失的句柄造成的,我会试着问C++库的开发人员来纠正这个问题,看看它是否解决了我在.NET 1.1上遇到的问题。

full image here

alt text http://img341.imageshack.us/img341/6923/process.png

+1

@Chris。如果它适用于2.0,为什么你需要使用1.1?你有没有试过红门性能分析器(这是非常好的)。 – 2010-05-20 12:48:22

+0

该工具已被编写在1.1和1.1是必需的框架。也许有一些可能转向框架2.0,但不确定。我将检查红色门探查器并希望它有帮助 – Drake 2010-05-20 14:02:22

+0

峰值内存使用情况列告诉你什么?另外,看起来你正在阅读250MB的信息,你最近怎么做? – 2010-05-20 14:58:36

回答

2

好的,既然你不能使用性能分析器,我可以想两件事来尝试。

1)这是一个愚蠢的/明显的问题。你是否绝对确定你正在处理一切实现IDispose?
即使您确定回去再次检查,请留意不会放置的临时物体,例如

string s = objA.GetAThing().ToString() 

其中GetAThing()返回一个实现IDispose的对象。

2)您是否尝试强制垃圾收集?
阅读Rico Mariani's Performance Tidbits,有时不仅可以致电GC.Collect(),有时候这是必要的。
我们有一个丰富的.Net winforms应用程序,我们需要需要来强制收集每十分钟左右。如果我们没有在几个小时后开始研究这个应用程序。

希望这有助于:)

UPDATE
那是一个耻辱。你有C++源代码吗?还是你坚持这个问题?

如果卡住了,您可以在终止当前实例的同时定期启动一个新实例。

您可以使用锁定的文件或Mutex来确保新实例在第一个终止之前不会开始处理。

+0

感谢您的回答,但我发现手柄问题是由我们用来与串行设备进行通信的C++库生成的。它然后发生在.NET 1.1和.NET 2.0中。不同之处在于,如果目标.NET 1.1应用程序的运行速度减慢/冻结,而不是.NET 2.0,则可以达到超过30000个句柄,而不会失去性能。 – Drake 2010-05-28 09:35:17

2

全面披露:我在Visual Studio中探查队。

编辑:以下是没有用的,因为VS Profiler不适用于.NET 1.1。你有没有尝试在探查器下运行你的代码? Visual Studio 2005/2008(开发版/团队套件)和Visual Studio 2010 Premium/Ultimate都有一个内置的分析器。还有第三方.NET分析器可用。

在profiler下运行你的代码会告诉你你的CPU在哪里做了很多工作。如果您只在性能下降的时间进行配置文件分析,结果应该可以帮助您了解原因。

或者,您可以模拟便宜的分析:调试您的应用程序并定期中断以查看调用堆栈上正在执行的操作。


另外,您的机器是否已安装.NET Framework 1.1 SP1?你能在其他机器上重现这个问题吗?

+0

感谢您的支持。这个问题可以在不同的机器上复制,并且所有SP1都安装完毕。我做了你建议的廉价分析,并且打印出堆栈级别的例程,但是堆栈级别似乎很低并且没有增长,总是小于50。您认为在运行时将VS Premium Profiler附加到.NET 1.1是否可能? – Drake 2010-05-20 09:07:29

+0

对不起,我真的忘了,VS Profiler不能用于.NET 1.1,所以不行,你不能使用它。对于“便宜的分析方法”,不要担心堆栈的深度,只需定期中断(10次左右),并跟踪执行的内容。如果你一直看到在堆栈顶部执行相同的方法,那么这应该有助于缩小问题的位置。 – 2010-05-20 09:10:32

1

首先,我会使用包含在窗口中的性能分析器,就像苔丝建议here

然后,我会使用windbg,因为她建议here

我只建议windbg第二,因为如果你还没有使用它,你需要一个小的WTF会话,直到你得到它(这是完全值得的)。也许通过玩弄柜台你可以找到问题。

1

有了这样的信息有限,它可能是一个亿的事情。

使用一点'禅'编程我会说,摆脱计时器,并开始使用线程。

使用具有取消标志的常规模式,并让测试在while循环中运行(如果这是它的需要)。

相关问题