2016-12-02 2 views
0

Когда я запускаю следующий код:Является ли System.Diagnostics.EventLog утечкой памяти?

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(); 
} 

Использование памяти начинается около 1 МБ, но подниматься очень быстро и не останавливается. Зачем ?

+0

ли вы уменьшаете свой цикл, чтобы увидеть, что произойдет, если ваша программа идет на ReadKey? – Sebastian

+1

Тот факт, что использование памяти растет, не обязательно означает, что вы «утечка» памяти, просто потому, что вы используете ее много. Утечка памяти происходит, когда использование не возвращается после того, как вы закончили то, что делаете, и переместились дальше, без надлежащего удаления ваших объектов (http://madgeek.com/articles/leaks/leaks.en.html). Сказав это, вы должны утилизировать() свой EventLog после использования, а затем ждать некоторое (неопределенное количество) времени, пока GarbageCollector не выполнит свою задачу. – Arie

+0

Фактически у меня есть эта утечка в службе windows, и утечка возникает только при использовании EventLog. Код выше - попытка воспроизвести утечку. @ Себастиан с 100 петлями, площадь памяти остается на высоком уровне. – gobes

ответ

1

код я использую для установки Windows Service с обозначенным журнала событий:

[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); 
    } 

код услуги:

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

Хотя, если я не могу объяснить, почему, с вашим кодом, утечка почти исчезла ... все еще небольшой подъем, но ничего по сравнению с предыдущим пиком! Спасибо :) – gobes