有一个应用程序包含三个可执行文件。其中之一 - 调度程序,运行其他可执行文件。调度程序在完成时从可执行文件接收代码。也就是说,只有调度程序始终在运行,其他可执行文件会卸载并再次加载。该应用程序在服务点运行并全天候工作。在第一次启动时,应用程序运行得很快。在一天结束时,应用程序运行速度非常慢。这种行为可能是什么原因?
答案 0 :(得分:7)
随着时间的推移,可能有很多原因导致减速。从缓慢的内存泄漏到反病毒的任何地方。您可以做的最好的事情是尝试构建关于首先查看应用程序区域的证据(数据)。尽量不与许多开发者交谈,因为每个人都会对可能出错的地方有不同的看法。获取数据!
如何获取数据:
perfmon perfmon是你的朋友。您可以查看许多计数器(系统范围以及特定于流程)。所以你可以从分析大4(那是内存,磁盘使用,cpu和网络)开始。有一个lot of posts关于什么计数器是最好的,所以我不会在这里详细介绍性能计数器。
windbg 如果你确实看到记忆力正在增长而没有被收集,那么现在是时候引进大枪了。 .NET非常适合从开发人员那里抽象内存使用,但这意味着我们必须在.NET下面找到不允许垃圾收集器完成其工作的内容。带有 sos.dll (托管扩展程序)的 windbg 是一个很棒的工具。 windbg中最困难的部分(根据我的经验)只是正确加载了sos扩展。您必须密切关注要分析的目标体系结构(64或32)以及正在运行的CLR版本。
procdump sysinternals的procdump是一个很好的小工具,可以从正在运行的进程中获取内存快照。然后可以通过windbg分析这些快照(.dmp文件)。
SOS 自v2以来,sos.dll随.NET Framework一起提供。使用v4,Visual Studio 2010集成了sos,允许您分析.dmp文件!
我发现最有用的内存泄漏的sos命令是:
!eeheap -gc (每个堆的每一代内容概述)
!dumpheap -min <size>
(转出特定<size>
上的所有对象和类型)
!dumpheap -type <type>
(转出特定<type>
的所有对象)
!gcroot <address>
(打印出一个堆栈,以便您可以看到GC中固定的父对象)
!执行<address>
(打印出特定对象的内存)
其他一些指示:
通常,您希望在负载下快照内存,因此最好有一些方法来从系统外部模拟内存。因此,最好提前运行,甚至将其用于应用程序的QA流程。
对于性能问题,通常最好使用正在运行的应用程序定期拍摄快照。然后,您可以在分析时比较快照。
嗯,这比我预想的要长一点,但希望值得!
答案 1 :(得分:1)
您必须检查调度程序应用程序的内存使用情况......似乎您没有处理未使用的对象。