2016-12-02 2 views
0

Wenn ich den folgenden Code:Leckt System.Diagnostics.EventLog Speicher?

static void Main(string[] args) 
{ 
    if (!System.Diagnostics.EventLog.SourceExists("eventSource")) 
    { 
     System.Diagnostics.EventLog.CreateEventSource("eventSource", ""); 
    } 

    System.Diagnostics.EventLog eventLog = new System.Diagnostics.EventLog();   
    eventLog.Source = "eventSource"; 
    eventLog.Log = ""; 

    for (int i = 0; i < 10000; i++) 
    { 
     Thread.Sleep(100); 

     eventLog.WriteEntry("test", EventLogEntryType.Information); 

     //I also tried the static method, the program still leaks 
     //System.Diagnostics.EventLog.WriteEntry("eventSource", "test", EventLogEntryType.Information); 
    } 

    Console.ReadKey(); 
} 

Der Speicherverbrauch um 1MB beginnt, sondern steigt sehr schnell und nicht zu stoppen. Warum ?

+0

Haben Sie Ihre Schleife reduzieren, um zu sehen, was passiert, wenn Ihr Programm geht für Schlüssel einlesen? – Sebastian

+1

Die Tatsache, dass die Speichernutzung ansteigt, bedeutet nicht unbedingt, dass Sie Speicher "verlieren", sondern nur, dass Sie viel davon verwenden. Ein Speicherleck tritt auf, wenn die Nutzung nicht wieder nachlässt, nachdem Sie Ihre Arbeit beendet und weitergegangen sind, ohne Ihre Objekte ordnungsgemäß zu entsorgen (http://madgeek.com/articles/leaks/leaks.en.html). Nachdem Sie dies getan haben, sollten Sie Ihr EventLog nach der Verwendung disposieren() und dann einige (unbestimmte) Zeit warten, bis GarbageCollector seine Sache macht. – Arie

+0

Eigentlich habe ich dieses Leck in einem Windows-Dienst, und das Leck tritt nur auf, wenn ich das EventLog benutze. Der obige Code ist ein Versuch, das Leck zu reproduzieren. @Sebastian mit 100 Schleifen, der Speicherbedarf auf einem hohen Niveau bleiben. – gobes

Antwort

1

Der Code Ich verwende Windows-Dienst mit einem bestimmten Ereignisprotokoll zu installieren:

[RunInstaller(true)] 
public partial class SampleServiceInstaller : System.Configuration.Install.Installer 
{ 
    private string SampleServiceName = string.Empty; 
    private string SampleLogName = string.Empty; 

    public SampleServiceInstaller() 
    { 
     this.SampleServiceName = "SampleService"; 
     this.SampleLogName = this.SampleServiceName + "Log"; 

     ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller(); 
     serviceProcessInstaller.Password = null; 
     serviceProcessInstaller.Username = null; 
     serviceProcessInstaller.Account = ServiceAccount.LocalSystem; 

     ServiceInstaller serviceInstaller = new ServiceInstaller(); 
     //This must be identical to the WindowsService.ServiceBase name 
     // set in the constructor of WindowsService.cs 
     serviceInstaller.ServiceName = this.SampleServiceName; 
     serviceInstaller.DisplayName = this.SampleServiceName; 
     serviceInstaller.StartType = ServiceStartMode.Automatic; 
     serviceInstaller.Description = "Sample Windows Service"; 

     // kill the default event log installer 
     serviceInstaller.Installers.Clear(); 

     // Create Event Source and Event Log     
     // This recreates the log every time the service is reinstaled (old messages are lost) 
     if (EventLog.SourceExists(this.SampleServiceName)) EventLog.DeleteEventSource(this.SampleServiceName); 
     System.Diagnostics.EventLogInstaller logInstaller = new System.Diagnostics.EventLogInstaller(); 
     logInstaller.Source = this.SampleServiceName; // use same as ServiceName 
     logInstaller.Log = this.SampleLogName; //can't be the same as service name 

     // Add all installers 
     this.Installers.AddRange(new Installer[] { 
        serviceProcessInstaller, serviceInstaller, logInstaller 
     }); 

    } 

    public override void Install(System.Collections.IDictionary savedState) 
    { 
     base.Install(savedState); 
    } 
    protected override void OnBeforeUninstall(System.Collections.IDictionary savedState) 
    { 
     base.OnBeforeUninstall(savedState); 
    } 

Servicecode:

public partial class SampleService : ServiceBase 
{ 
    /// <summary> 
    /// Designer variable. 
    /// </summary> 
    private System.ComponentModel.IContainer components = null; 

    /// <summary> 
    /// Event log for the service 
    /// </summary> 
    EventLog serviceLog; 

    /// <summary> 
    /// Public Constructor for WindowsService. 
    /// - Initialization code here. 
    /// </summary> 
    public SampleService() 
    { 
     InitializeComponent(); 
    } 

    /// <summary> 
    /// The Main Thread: list of services to run. 
    /// </summary> 
    static void Main() 
    { 
     ServiceBase[] ServicesToRun; 
     ServicesToRun = new ServiceBase[] { new SampleService() }; 
     ServiceBase.Run(ServicesToRun); 
    } 

    /// <summary> 
    /// Startup code 
    /// </summary> 
    /// <param name="args"></param> 
    protected override void OnStart(string[] args) 
    { 
     base.OnStart(args); 
     // 
     // run your own start code here 
     // 
     serviceLog.WriteEntry("My service started", EventLogEntryType.Information, 0); 
    } 

    /// <summary> 
    /// Stop code 
    /// </summary> 
    protected override void OnStop() 
    { 
     // 
     // run your own stop code here 
     // 
     serviceLog.WriteEntry("My service stopped", EventLogEntryType.Information, 0); 

     base.OnStop(); 
    } 

    /// <summary> 
    /// Cleanup code 
    /// </summary> 
    /// <param name="disposing"></param> 
    protected override void Dispose(bool disposing) 
    { 
     // 
     // do disposing here 
     // 

     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

    /// <summary> 
    /// Pause code 
    /// </summary> 
    protected override void OnPause() 
    { 
     base.OnPause(); 
     // 
     // code to run if service pauses 
     // 
    } 

    /// <summary> 
    /// Continue code 
    /// </summary> 
    protected override void OnContinue() 
    { 
     base.OnContinue(); 
     // 
     // code tu run when service continues after being paused 
     // 
    } 

    /// <summary> 
    /// Called when the System is shutting down 
    /// - when special handling 
    /// of code that deals with a system shutdown, such 
    /// as saving special data before shutdown is needed. 
    /// </summary> 
    protected override void OnShutdown() 
    { 
     // 
     // code tu run when system is shut down 
     // 
     base.OnShutdown(); 
    } 

    /// <summary> 
    /// If sending a command to the service is needed 
    /// without the need for Remoting or Sockets, 
    /// this method is used to do custom methods. 
    /// int command = 128; //Some Arbitrary number between 128 & 256 
    /// ServiceController sc = new ServiceController("NameOfService"); 
    /// sc.ExecuteCommand(command); 
    /// </summary> 
    /// <param name="command">Arbitrary Integer between 128 & 256</param> 
    protected override void OnCustomCommand(int command) 
    { 
     base.OnCustomCommand(command); 
     // 
     // handle custom code here 
     // 
    } 

    /// <summary> 
    /// Useful for detecting power status changes, 
    /// such as going into Suspend mode or Low Battery for laptops. 
    /// </summary> 
    /// <param name="powerStatus">The Power Broadcast Status 
    /// (BatteryLow, Suspend, etc.)</param> 
    protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus) 
    { 
     // 
     // handle power events here 
     // 
     return base.OnPowerEvent(powerStatus); 
    } 

    /// <summary> 
    /// To handle a change event 
    /// from a Terminal Server session. 
    /// Useful if determining 
    /// when a user logs in remotely or logs off, 
    /// or when someone logs into the console is needed. 
    /// </summary> 
    /// <param name="changeDescription">The Session Change 
    /// Event that occured.</param> 
    protected override void OnSessionChange(SessionChangeDescription changeDescription) 
    { 
     // 
     // handle session change here 
     // 
     base.OnSessionChange(changeDescription); 
    } 

    private void InitializeComponent() 
    { 
     components = new System.ComponentModel.Container(); 
     // first 8 letters should be unique 
     this.ServiceName = "SampleService"; 

     // if you want to log service event to log registered while installing the service 
     string newLogName = this.ServiceName + "Log"; 
     string newSourceName = this.ServiceName; 

     if (!EventLog.SourceExists(newSourceName)) 
     { 
      EventLog.CreateEventSource(newSourceName, newLogName); 
     } 
     serviceLog = new EventLog(); 
     serviceLog.Source = newSourceName; 
     serviceLog.Log = newLogName; 

     // Causes log to be disposed when the service is disposed 
     components.Add(serviceLog); 

     // Flags set whether or not to handle that specific type of event. 
     this.CanHandlePowerEvent = true; 
     this.CanHandleSessionChangeEvent = true; 
     this.CanPauseAndContinue = true; 
     this.CanShutdown = true; 
     this.CanStop = true; 

    } 
} 
+0

Obwohl, wenn ich nicht erklären kann, warum, mit Ihrem Code ist das Leck fast weg ... es gibt immer noch einen kleinen Anstieg, aber nichts im Vergleich zum vorherigen Höhepunkt! Vielen Dank :) – gobes

Verwandte Themen