简体   繁体   中英

ManagementEventWatcher Memory Leak Issue

I might be using the term Memory Leak poorly but I'm not sure of any other way to describe it. I have wrote a Windows Service that uses the ManagementEventWatcher class to watch for the launch of a specific instance. Once it sees that instance, it launches another in response. I have managed to successfully test this service on multiple computers with success across the board.

The issue I run into is that when the service launches it uses on average 2400k. However, leaving the services running overnight I find in the morning the process sits at 12000k of private working memory in task manager.

This leads me to believe that the something is not disposing of events but I can not discern what.

I believe it might have something to do with the event arrive line: watcher.EventArrived += new EventArrivedEventHandler...

I believe this because it requires use of the add assignment operator. I'd to test this theory but I'm having trouble discerning where I would place the minus assignment operator. Would directly after the first line clear the line to prevent pooling? Or does anyone see any glaring obvious cleanup methods that I'm missing? Attached is the code that is called by the service:

class Monitor
{
    //Pulls process watching and launch path as well as args from xml config file.
    private static string procWatch = ConfigurationManager.AppSettings["watchFor"];
    private static string filePath = ConfigurationManager.AppSettings["filePath"];
    private static string filePath2 = ConfigurationManager.AppSettings["filePath2"];

    public static ManagementEventWatcher watchforProcess()
    {       
        //Creates ManagementEventWatcher Object to return to the service.
        ManagementScope scope = new ManagementScope(@"\\.\root\CIMV2");
        WqlEventQuery query = new WqlEventQuery("__InstanceCreationEvent", new TimeSpan(0, 0, 1), "TargetInstance isa \"Win32_Process\"");
        ManagementEventWatcher watcher = new ManagementEventWatcher(scope, query);
        watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
        return watcher;
    }
    public static void watcher_EventArrived(object sender, EventArrivedEventArgs e)
    {
        //Event handler that launches a process if it's name matches proc watch
        string instanceName = ((ManagementBaseObject)e.NewEvent["TargetInstance"])["Name"].ToString();
        if (instanceName.ToLower() == procWatch)
        {
            EventLog.WriteEntry("KaceWatcher", "Kace process found.");
            Process.Start(filePath, filePath2);             
        }
        //Should I place a null here to clear up each instanceName.
    }
    public static void finalize()
    {
        //Used for service stop
        procWatch = null;
        filePath = null;
        filePath2 = null;
    }


}

We just experienced the same issue after using ManagementEventWatcher , except much more extreme, memory usage skyrocketing into multi-GB-range since we're getting WMI events fired often.

It turns out the solution was, in the EventArrived event you need to manually call Dispose() on e.NewEvent . You are missing the same cleanup.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM