有一个包含三个可执行文件的应用程序。其中之一-调度程序,运行其他可执行文件。调度程序在完成时从可执行文件接收代码。也就是说,仅调度程序始终处于运行状态,其他可执行文件将卸载并再次加载。该应用程序在服务点运行,并全天候工作。在首次启动时,该应用程序可以快速运行。最终,该应用程序的运行速度非常慢。发生这种行为的原因可能是什么?
最佳答案
随着时间的流逝,可能有很多原因。从缓慢的内存泄漏到防病毒。您能做的最好的事情就是尝试建立有关应用程序首先要查找的区域的证据(数据)。尽量不要与许多开发人员讨论,因为每个人对于可能出什么问题都会有不同的看法。获取数据!
如何获取数据:
perfmon
perfmon是您的朋友。您可以查看很多计数器(系统范围以及特定于过程的计数器)。因此,您可以从分析大四(内存,磁盘使用率,CPU和网络)开始。关于哪种计数器最好,这里有一个lot of posts,所以在这里我不会对性能计数器进行过多的介绍。
windbg
如果您确实看到记忆正在增长并且没有被收集,那么该是大手笔了。 .NET擅长从开发人员那里提取内存使用量,但这意味着我们有时必须深入.NET之下,以找出不允许垃圾收集器执行其工作的原因。带有sos.dll(托管扩展)的windbg对此非常有用。以我的经验,windbg最难的部分就是正确加载sos扩展。您必须密切注意要分析的目标体系结构(64或32)以及运行的CLR版本。
procdump
sysinternals的procdump是一个很棒的小工具,可以从正在运行的进程中获取内存快照。然后可以通过windbg分析这些快照(.dmp文件)。
s
从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中固定了哪个父对象)
!do <address>
(打印出特定对象的内存)
其他一些指针:
通常,您希望对负载下的内存进行快照,因此最好采用某种方法从系统外部进行模拟。因此,最好提前运行它,甚至将其纳入应用程序的质量检查流程中。
对于性能问题,通常最好随运行的应用程序定期拍摄常规快照。然后,您可以在分析时比较快照。
好吧,这比我预期的要长一点,但是希望它值得!