Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a memory leak or will garbage collection fix it

Lets say I have a button that gets clicked and it does this:

public void ButtonClick(object sender, EventArgs e)
{
  System.Timers.Timer NewTimer = new System.Timers.Timer();
  NewTimer.AutoReset = false;
  NewTimer.Elapsed += new ElapsedEventHandler(TimerElapsed);
  NewTimer.Interval = 1000;
  NewTimer.Start(); 
}

public void TimerElapsed(object sender, ElapsedEventArgs e)
{

}

If this button gets clicked 100 times what happens to those instances that have been created? Will garbage collection kick in or does the System.Timers.Timer.Close method need calling and if it does where do you call it from?

like image 264
Jon Avatar asked Jan 17 '23 10:01

Jon


1 Answers

No this will not cause a memory leak. In fact the way your code is written it's not guaranteed to execute properly. Timers.Timer is really just a wrapper over Threading.Timer and it's explicitly listed as being collectable even if it's currently running.

http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx

Here you keep no reference to it and hence the very next GC could collect it while your form is still running and before the event ever fires

EDIT

The documentation for Timers.Timer appears to be incorrect. The Timer instance will not be collected if it's unreferenced. It will indeed live on

var timer = new System.Timers.Timer
{
    Interval = 400,
    AutoReset = true
};
timer.Elapsed += (_, __) => Console.WriteLine("Stayin alive (2)...");
timer.Enabled = true;

WeakReference weakTimer = new WeakReference(timer);
timer = null;

for (int i = 0; i < 100; i++)
{
    GC.Collect();
    GC.WaitForPendingFinalizers();
}

Console.WriteLine("Weak Reference: {0}", weakTimer.Target);
Console.ReadKey();
like image 113
JaredPar Avatar answered Feb 03 '23 23:02

JaredPar