Windows Service增加CPU消耗 - c#

在我的工作中,我负责使用C#2003编写的六个Windows服务。每个服务都包含一个计时器,该计时器每分钟左右触发一次,大部分工作都在该计时器上进行。

我的问题是,随着这些服务的运行,即使没有任何有意义的工作要做,它们也会在循环的每次迭代中消耗越来越多的CPU时间(即,它们只是闲着,浏览数据库)做某事)。当它们启动时,每个服务平均使用4个CPU的(大约)2-3%,这很好。 24小时后,每个服务将在其循环运行期间消耗整个处理器。

有人可以帮忙吗?我不知道是什么原因造成的。我们当前的解决方案是每天重启一次服务(它们会自行关闭,然后脚本会发现它们处于脱机状态,并在凌晨3点左右重启它们)。但这不是一个长期的解决方案。我担心的是,随着服务变得越来越繁忙,每天重启一次可能还不够...但是由于存在一个巨大的启动惩罚(它们全部使用NHibernate进行数据访问),因为它们变得越来越繁忙,所以我们并没有这样做想要做的就是更频繁地重新启动它们。

@akmad:是的,这很困难。

是的,随着时间的推移,单独运行的服务将显示相同的症状。
不,不是。我们已经看过了。这可能发生在上午10点或下午6点或深夜。没有一致性。
我们的确是;他们是。这些服务完全按照应有的方式工作,而没有其他任何事情。
不幸的是,这需要准确地预知服务将在何时达到CPU的最大化,这是无法预料的,​​并且永远不会很快发生……这使事情变得非常困难,因为我的老板会在开始拥有服务时运行并重新启动它们问题而无需考虑调试问题。
不,他们使用的内存量是相当稳定的(每个内存约60-80MB,计算机上的4GB内存除外)。

好的建议,但请放心,我们已经尝试了所有常见的故障排除方法。我希望这是一个人们可能知道的.NET问题,我们可以进行解决。我老板的解决方案(我强烈不希望实现)是在数据库中放置一个字段,该字段保存多次以使服务在一天中重新启动,这样他就可以解决问题,而不必考虑它。我正拼命地寻找真正问题的原因,以便能够解决它,因为该解决方案将在大约六个月内成为灾难。

@Yaakov Ellis:它们各自具有不同的功能。有人从异地的Oracle数据库中读取记录;另一个处理这些记录并将属于这些记录的文件传输到我们的系统中;第三位检查这些文件,以确保它们与我们期望的一样;另一个是维护服务,它会不断检查磁盘空间(我们有足够的空间)之类的东西,并轮询其他服务器以确保它们仍然有效。一个正在运行只是为了确保所有其他所有这些都在运行并且正在执行它们的工作,监视和报告错误,并重新启动所有无法使整个系统每天24小时运行的故障。

因此,如果您要问的是我想问的问题,那么不行,所有这些服务(通过NHibernate进行数据库访问除外)都没有一个我可以指出的潜在问题。不幸的是,如果事实证明这是实际的问题(这不会令我感到惊讶),那么整个过程可能会搞砸了-我最终将用简单的SQL重写所有这些问题。我希望这是一个垃圾收集器问题,或者比NHibernate更容易处理的问题。

@乔希丹:没有秘密。正如我所说,我们已经尝试了所有常见的故障排除方法。分析没有帮助:我们使用的探查器无法指向CPU使用率较高时实际执行的任何代码。这些服务大约一个月前被撕裂,以寻找此问题。对代码的每个部分都进行了分析,以试图弄清我们的代码是否是问题所在。我不是在这里问,因为我还没有做完作业。如果这是一个简单的案例,说明服务所做的工作比预期的多,那是本应被发现的。

这里的问题是,在大多数情况下,服务根本不执行任何操作,但仍然消耗了四个CPU内核的25%或更多:它们找不到任何工作要做,退出循环并等待下一次迭代。从字面上看,这几乎不需要占用任何CPU时间。

这是我们看到的一个行为示例,该服务在两天都没有工作要做的服务上(在不变的环境中)。这是上周捕获的:

第1天,上午8点:平均CPU使用率约3%
第1天,下午6点:平均CPU使用率约8%
第2天,上午7点:平均CPU使用率约20%
第2天,上午11点:平均CPU使用率约30%

在查看了所有可能的世俗原因之后,我在这里提出了这个问题,因为我认为(正确的是,事实证明)我会得到更多创新的答案(例如Ubiguchi的答案),或者指向我没有的东西的指针没想到(就像伊恩的建议一样)。

CPU峰值是否也会发生
紧接计时器之前
回调,在计时器回调中,
或立即跟随计时器
打回来?

你误会了。这不是一个峰值。如果是这样,那将没有问题。我可以应付尖峰。但这不是... CPU使用率总体呈上升趋势。即使服务什么也不做,也要等待下一个计时器命中。当服务启动时,一切都会变得平静起来,并且该图看起来就像您所期望的...通常,使用率为0%,随着NHibernate命中数据库或该服务完成了一些琐碎的工作,峰值会上升到10% 。但这在过程运行时始终会提高到全盘使用率的25%(如果我让它走得太远的话会更多)。

这使伊恩的建议成为合乎逻辑的灵丹妙药(NHibernate在您不看时会做很多事情)。 las,我已经实现了他的解决方案,但是没有起到任何作用(我没有证明这一点,但是我实际上认为这使情况变得更糟了……现在平均使用率似乎增长得更快)。请注意,剥离NHibernate的“节”(如您所建议的)是不可行的,因为那样会剥离服务中约90%的代码,这将使我排除计时器是一个问题(我绝对打算这样做)尝试),但不能帮助我排除NHibernate的问题,因为如果NHibernate导致了此问题,那么已实施的躲避错误的修补程序(请参见下文)就必须成为系统工作方式;我们非常依赖NHibernate进行此项目,以至于PM根本不接受这会导致无法解决的结构问题。

我刚刚注意到了一种绝望感
问题-您的问题
将继续禁止一个小奇迹

并不意味着它会那样消失。目前,这些服务每天都在重新启动(可以选择输入一天中的任何时间以关闭和重新启动它们),这修补了该问题,但一旦将其投入生产机器,就不能成为长期解决方案开始变得忙碌无论是解决问题还是由PM维护,这些问题都不会继续存在。显然,我希望实施一个真正的修复程序,但是由于最初的测试没有显示出这样做的原因,并且已经对服务进行了广泛的审查,因此项目经理宁愿让它们重新启动多次,也不想花费更多时间尝试修复它们。 。那完全是我无法控制的,这使您正在谈论的奇迹比原本更重要。

那是非常有趣的
因为您信任自己的分析器)。

我不。但是,这些是在Windows 2000计算机上运行的.NET 1.1中编写的Windows服务,由狡猾的Nant脚本部署,使用旧版本的NHibernate进行数据库访问。我实际上会说我信任的那台机器上几乎没有。

参考方案

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

如果不是,则加载到内存中的对象映射的大小将随着时间的推移逐渐增加,并且每次会话刷新将占用越来越多的CPU时间。

在硬件级别模拟按键-Windows - java

我正在寻找一种语言或库,以使我可以尽可能地模拟按键,而无需实际按下按键。(我对按键级别的具体衡量标准是,当我的计算机已经在运行按键侦听器(例如MouseKey和StickyKeys)时,它是否会产生与物理按键相同的输出。)我已经尝试了许多模拟按键的方法。Java AWT库,Java win32api,python win32com sendKeys,pyth…

SQLite。修复sqlite-net-wp8项目依赖项 - c#

为什么SQLGet在NuGet上不可用?为什么它是Visual Studio的一部分,您必须在“工具”->“扩展和更新”中查找更新?在过去的几个月中,我开始对Windows 8和Windows Phone 8进行编码,我希望对此有所了解。对我来说,在Windows 8项目上使用SQLite会创建VS级依赖关系。假设我使用Visual Studio ID…

Windows Media Player如何处理监视器的刷新率? - c#

我正在C#/ WinForms中编写动画应用程序(请参见this question)。基本上,我应用程序中的动画是平滑的,但显示出撕裂效果;当我拍摄相同的动画并将其渲染为AVI文件并使用Windows Media Player播放时,该动画完全没有显示撕裂效果。我知道WMP不会更改帧速率,因为动画与音乐同步。我假设WMP使用DirectX或其他知道监视器刷新…

Windows 8 Metro应用程序的图表 - c#

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely …

如何在Universal Windows App中使用BackgroundMediaPlayer播放内部声音 - c#

我在C#中创建一个计时器。计时器结束后,用户将收到通知。如果我的应用程序被暂停,我会使用ToastNotificationManager安排通知,并在Toast XML中将声音设置为内部声音,例如:<audio src='ms-winsoundevent:Notification.Looping.Alarm10' loop=…