【问题标题】:Long running application slows down长时间运行的应用程序变慢
【发布时间】:2012-03-15 16:59:36
【问题描述】:

有一个由三个可执行文件组成的应用程序。其中之一 - 调度程序,它运行其他可执行文件。调度程序在其完成时从可执行文件接收代码。也就是说,只有调度程序始终在运行,其他可执行文件卸载并再次加载。该应用程序在服务点上运行并全天候工作。在第一次启动时,应用程序运行速度很快。归根结底,该应用程序的运行速度非常慢。这种行为的原因可能是什么?

【问题讨论】:

  • 重复订阅同一个事件会这样做。只要您不使用调试器,这只是一个猜测练习。

标签: c# .net memory memory-leaks appdomain


【解决方案1】:

随着时间的推移,速度变慢可能有很多原因。从缓慢的内存泄漏到防病毒的任何地方。您能做的最好的事情是尝试构建关于首先查看应用程序的哪个区域的证据(数据)。尽量不要与许多开发人员讨论它,因为每个人都会对可能出现的问题有不同的看法。获取数据!

如何获取数据:

perfmon perfmon 是你的朋友。您可以查看很多计数器(系统范围的以及特定于进程的)。因此,您可以从分析四大(即内存、磁盘使用情况、cpu 和网络)开始。那里有一个lot of posts 告诉你什么计数器是最好的,所以我不会在这里详细介绍性能计数器。

windbg 如果您确实看到内存正在增长并且没有被收集,那么是时候引入大炮了。 .NET 非常擅长从开发人员那里抽象出内存使用,但这意味着我们有时必须深入 .NET 以找出哪些原因不允许垃圾收集器完成其工作。 windbg 和 sos.dll(托管扩展)是一个很好的工具。 windbg 最困难的部分(以我的经验)只是正确加载 sos 扩展。您必须密切注意正在分析的目标架构(64 或 32)以及正在运行的 CLR 版本。

procdump sysinternals 的 procdump 是一个很棒的小实用程序,可以从正在运行的进程中获取内存快照。然后,windbg 可以分析这些快照(.dmp 文件)。

sos sos.dll 自 v2 起随 .NET Framework 一起提供。在 v4 中,Visual Studio 2010 集成了 sos 并允许您分析 .dmp 文件!

我发现最有用的用于内存泄漏的 sos 命令是:

!eeheap -gc(每个堆的每一代的概述)

!dumpheap -min <size>(转储所有对象和类型,在特定的 <size> 上)

!dumpheap -type <type>(转储出特定 <type> 的所有对象)

!gcroot <address>(打印出一个堆栈,这样您就可以看到哪个父对象在 GC 中固定)

!do <address>(打印出特定对象的内存)

其他一些建议:

通常,您希望在负载下对内存进行快照,因此最好有某种方法从系统外部模拟它。因此,最好提前运行它,甚至将其用于应用程序的 QA 流程。

对于性能问题,通常最好使用正在运行的应用程序随时间定期拍摄快照。然后您可以在分析时比较快照。

嗯,这比我预期的要长一点,但希望值得!

【讨论】:

  • 很棒的答案。我要补充一点,我选择的第一个工具就是配置任务管理器并观察资源分配的动态。
  • 但是如果exe被终止,资源怎么可能没有释放呢? EXE 通过 Application.Exit(int) 自行终止。调度程序只是一个最顶层的窗口。没有什么东西会导致内存泄漏(我猜)。
  • @EngineerSpock 然后,首先测量系统级资源(CPU、内存、磁盘和网络)。接下来,找出哪个进程导致其中一个出现峰值。优化您的搜索并重新开始。这确实需要时间,但坚持不懈,你会找到原因的。
【解决方案2】:

您必须检查调度程序应用程序的内存使用情况...看来您没有处理未使用的对象。

【讨论】:

    猜你喜欢
    • 2018-02-24
    • 1970-01-01
    • 2015-06-27
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 2012-04-18
    • 2016-10-07
    相关资源
    最近更新 更多