Windows服务增加CPU消耗

时间:2008-08-25 14:45:54

标签: c# nhibernate windows-services .net-1.1

7 个答案:

答案 0 :(得分:3)

你提到你正在使用NHibernate - 你是否在适当的时候关闭你的N​​Hibernate会话(例如每次迭代结束?)

如果没有,那么加载到内存中的对象映射的大小将逐渐增加,每次会话刷新将占用更多的CPU时间。

答案 1 :(得分:3)

这是我开始的地方:

  1. 获取Process Explorer并显示JIT中的%时间,GC中的%时间,CPU周期增量,CPU时间,CPU%和线程。
  2. 您还需要内核和用户时间,以及一些代表性的堆栈跟踪,但我认为您必须点击“属性”才能获取快照。
  3. 比赛前后比较。
  4. 关于可能性的几点想法:

    • GC过多(GC上升的时间百分比。此外,Perfmon GC和CPU计数器也会对应)
    • 过多的线程和相关的上下文切换(线程数上升)
    • 轮询(堆栈跟踪始终在单个函数中捕获)
    • 内核时间过长(内核时间很长 - 任务管理器在CPU高时显示大内核时间数)
    • 例外(PE .NET选项卡抛出的异常很高并且越来越高。还有一个Perfmon计数器)
    • 病毒/ rootkit(好吧,这是最后一个沟渠情况 - 但是可以构建一个隐藏在TaskManager中的rootkit。我怀疑如果你足够狡猾,你可以将不可避免的CPU使用量分配给另一个进程此外,如果你已经排除了上述所有内容,我现在就没有想法了。)

答案 2 :(得分:2)

远程调试你的未知应用程序显然很困难......但这里有一些我要看的东西:

  1. 当您一次只运行其中一项服务时会发生什么?你还看到减速吗?这可能表明服务之间存在争议。
  2. 问题是否总是在同一时间发生,无论服务运行多长时间?这可能表明其他东西(备份,病毒扫描等)导致机器(或数据库)整体变慢。
  3. 您是否有日志记录或其他一些机制来确保该服务仅按您认为的那样经常工作?
  4. 如果您可以在短时间内看到性能下降,请尝试运行该服务一段时间,然后附加一个分析器以查看与CPU挂钩的确切内容。
  5. 您没有提及有关内存使用情况的任何内容。你有这些服务的信息吗?您可能会耗尽大部分RAM并导致磁盘丢失,或者出现类似问题。
  6. 祝你好运!

答案 3 :(得分:2)

我建议将这个问题分解成碎片 首先,找到一种方法,100%的时间和快速重现问题。降低计时器,以便更频繁地启动服务(例如,比正常情况快10倍)。如果问题出现的速度要快10倍,那么它与迭代次数有关,而与实时或服务所做的实际工作无关。而且您将能够比一天更快地完成后续步骤 其次,注释掉所有实际工作代码,并只让服务,定时器和同步机制。如果问题仍然出现,那么它将出现在代码的那一部分中。 如果没有,则开始添加您注释掉的代码,一次一个。最后,您应该找出导致问题的代码部分。

答案 4 :(得分:1)

'Fra这个答案只是建议您查看一些方向,但在.NET Windows服务中遇到过类似问题我有一些想法可能会对您有所帮助。

我的第一个建议是你的服务可能在处理内存方面或者处理非托管内存的方式上有一些错误。我最后一次跟踪类似的问题时发现了第三方OSS库,我们使用存储句柄来处理静态内存中的非托管对象。服务运行的时间越长,处理的服务就越多,这导致进程的CPU性能很快就会下降。尝试解决此类问题的方法是确保您的服务在计时器调用之间不存储任何内存,尽管如果您的第三方库使用静态内存,您可能需要做一些聪明的事情,例如为计时器调用和沟渠创建应用程序域处理完成后,应用程序doamin(及其静态内存)。

我在类似情况下看到的另一个问题是定时器同步代码是可疑的,这实际上允许多个线程一次运行处理代码。当我们调试代码时,我们发现第一个线程阻塞了第二个,当第二个线程开始时,第三个线程被阻止了。随着时间的推移,阻塞持续时间越来越长,因此CPU使用量也越来越高。我们用来解决这个问题的解决方案是实现正确的同步代码,这样只有在没有被阻塞的情况下,计时器才会启动另一个线程。

希望这会有所帮助,但如果我的想法都是红色的话,那么我们会道歉。

答案 5 :(得分:1)

听起来像计时器的线程问题。您可能有一个工作单元阻止另一个工作在不同的工作线程上运行,导致它们在每次计时器触发时都会堆叠起来。或者你的生活和工作时间可能超出预期。

我建议重构计时器。将其替换为在ThreadPool上排队工作的单个线程。您可以Sleep()线程来控制查找新工作的频率。确保这是代码多线程的唯一位置。所有其他对象应该被实例化,因为工作准备好进行处理并在完成工作后销毁。状态是多线程代码中的敌人。

缺少设计的另一个领域似乎是您有多个服务轮询资源来执行某些操作。我建议在一项服务下统一它们。他们可能分开做事,但他们齐心协力;你只是使用文件系统,数据库等作为方法调用的替代。还有,2003年?我为你感到难过。

答案 6 :(得分:0)

  

很好的建议,但请放心,我们已经尝试了所有常见的故障排除方法。我希望这是一个有人可能知道的.NET问题,我们可以解决这个问题。

我的感觉是,无论底层原因多么奇怪,通常的故障排除步骤都是您找到问题的最佳选择。

由于这是性能问题,因此良好的测量值非常宝贵。整个过程CPU的使用范围太广了。 哪里是您的服务花费时间?您可以使用分析器来测量它,或者只记录各个部分的开始和停止。如果你无法做到这一点,那么请使用Andrea Bertani的建议 - 通过删除其他部分来隔离部分。

一旦找到了常规区域,就可以进行更细粒度的测量,直到您理清CPU使用情况的来源。如果在这一点上如何解决问题并不明显,那么你至少需要弹药来解决更具体的问题。

如果您事实上已经完成了所有这些常规故障排除,请让我们知道这个秘密。