微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

运行windows服务观看服务运行增长内存泄漏

我已经检查了所有post,但到目前为止还找不到解决scheme。 我没有设置一个servlets,只应监视我想要监视的其他服务是否运行,如果不是,请重新启动它,并在应用程序事件日志中放置一条消息。

服务本身效果很好,没有什么特别的:),但是当我启动服务时,它使用了大约1.6MB的内存,每10秒钟就会增长到60-70k,这对于它来说是非常有用的。 我尝试了处理并清除所有资源。 尝试与System.Timers的工作,而不是实际的解决scheme,但没有真正的工作,因为我想要的,内存仍然在增长。

在debugging或发行版本没有区别,我在.Net 2上使用它,不知道它是否对你有影响3,3.5或4。

任何提示

Windows Server 2003上的内存使用情况说明

C Linux从内存读取/写入字(段,偏移量)

内存分配在DLL返回空指针

如何在Python中使用psutil获得程序的最大内存使用率

Gzip内存压缩

using System; using System.IO; using System.Diagnostics; using System.ServiceProcess; using System.Threading; using System.Timers; namespace Watchguard { class WindowsService : ServiceBase { Thread mWorker; AutoResetEvent mStop = new AutoResetEvent(false); /// <summary> /// Public Constructor for WindowsService. /// - Put all of your Initialization code here. /// </summary> public WindowsService() { this.ServiceName = "Informer Watchguard"; this.EventLog.source = "Informer Watchguard"; this.EventLog.Log = "Application"; // These Flags set whether or not to handle that specific // type of event. Set to true if you need it,false otherwise. this.CanHandlePowerEvent = false; this.CanHandleSessionChangeEvent = false; this.CanPauseAndContinue = false; this.CanShutdown = false; this.CanStop = true; if (!EventLog.sourceExists("Informer Watchguard")) EventLog.CreateEventSource("Informer Watchguard","Application"); } /// <summary> /// The Main Thread: This is where your Service is Run. /// </summary> static void Main() { ServiceBase.Run(new WindowsService()); } /// <summary> /// dispose of objects that need it here. /// </summary> /// <param name="disposing">Whether or not disposing is going on.</param> protected override void dispose(bool disposing) { base.dispose(disposing); } /// <summary> /// OnStart: Put startup code here /// - Start threads,get inital data,etc. /// </summary> /// <param name="args"></param> protected override void OnStart(string[] args) { base.OnStart(args); MyLogEvent("Init"); mWorker = new Thread(WatchServices); mWorker.Start(); } /// <summary> /// OnStop: Put your stop code here /// - Stop threads,set final data,etc. /// </summary> protected override void OnStop() { mStop.Set(); mWorker.Join(); base.OnStop(); } /// <summary> /// OnSessionChange(): To handle a change event from a Terminal Server session. /// Useful if you need to determine when a user logs in remotely or logs off,/// or when someone logs into the console. /// </summary> /// <param name="changeDescription"></param> protected override void OnSessionChange(SessionChangeDescription changeDescription) { base.OnSessionChange(changeDescription); } private void WatchServices() { string scName = ""; ServiceController[] scServices; scServices = ServiceController.GetServices(); for (; ; ) { // Run this code once every 10 seconds or stop right away if the service is stopped if (mStop.WaitOne(10000)) return; // Do work... foreach (ServiceController scTemp in scServices) { scName = scTemp.ServiceName.ToString().ToLower(); if (scName == "InformerWatchguard") scName = ""; // don't do it for yourself if (scName.Length > 8) scName = scName.Substring(0,8); if (scName == "informer") { ServiceController sc = new ServiceController(scTemp.ServiceName.ToString()); if (sc.Status == ServiceControllerStatus.Stopped) { sc.Start(); MyLogEvent("Found service " + scTemp.ServiceName.ToString() + " which has status: " + sc.Status + "nRestarting Service..."); } sc.dispose(); sc = null; } } } } private static void MyLogEvent(String Message) { // Create an eEventLog instance and assign its source. EventLog myLog = new EventLog(); myLog.source = "Informer Watchguard"; // Write an informational entry to the event log. myLog.WriteEntry(Message); } } }

读取内存时出现访问冲突

Windows上大量连续的虚拟内存分配

位字段的内存pipe理在C.

C / C ++程序中如何存在静态地址?

为什么Linux中的物理内存被分配线性增加而不是一次?

你的代码可能会在循环内部抛出一个异常,但是这些异常不会被捕获。 所以,如下更改代码来捕捉异常:

if (scName == "informer") { try { using(ServiceController sc = new ServiceController(scTemp.ServiceName.ToString())) { if (sc.Status == ServiceControllerStatus.Stopped) { sc.Start(); MyLogEvent("Found service " + scTemp.ServiceName.ToString() + " which has status: " + sc.Status + "nRestarting Service..."); } } } catch { // Write debug log here } }

你可以在调查之后去掉外部的try / catch,留下using语句来确保dispose调用即使抛出异常。

至少,您需要在日志记录代码中执行此操作,因为EventLog需要dispose() d。 似乎这个资源可以被重复使用,而不是在每个电话上都new 。 您也可以考虑在您的主循环中使用ServiceController对象,以使您的代码更加安全。

private static void MyLogEvent(String Message) { // Create an eEventLog instance and assign its source. using (EventLog myLog = new EventLog()) { myLog.source = "Informer Watchguard"; // Write an informational entry to the event log. myLog.WriteEntry(Message); } }

这应该移到循环中,因为您不希望在服务期间保留对旧服务句柄的引用:

ServiceController[] scServices = ServiceController.GetServices();

您还想要处理对EventLog和ServiceController实例的引用。 正如Artem所指出的那样,注意那些阻止你这样做的例外。

由于记忆每10秒钟上升一次,它必须是你的循环中的东西。

如果内存上升,无论您是否写入EventLog,那么这不是主要问题。

记忆用过吗? 也就是垃圾收集器踢了一段时间? 您可以在返回睡眠之前通过执行GC.Collect()来测试GC的效果(尽管在生产中我会小心使用它)。

我不确定我完全理解这个问题。 您要监控的服务是否始终如一? 从你的代码中可以看出答案是肯定的,如果是这样的话,你可以简单地创建ServiceController类实例,将服务名称传递给构造函数。 在你的线程例程中,你要继续循环,直到发出停止,并且WaitOne方法调用返回一个布尔值,所以while循环似乎是合适的。 在while循环中,您可以调用ServiceController类实例的Refresh方法获取服务的当前状态。 事件日志记录应该很简单,需要调用静态方法EventLog.WriteEntry方法之一,至少要传递消息和源代码“Informer Watchguard”当你从线程例程中的循环退出时,可以放弃ServiceController实例所有这一切意味着您正在创建更少的需要处理的对象,因此不太可能存在某些资源泄漏。

感谢所有的建议。 最后,这项服务现在有一些修改是稳定的。

@Steve:我看到很多服务都是以“Informer …”的名字开始的,但我不知道全名,所以我就这样去了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐