Is a memory leak or garbage collection correcting it

Let's say that I have a button that is pressed 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 100 times, what happens to instantiated instances? Will garbage collection come in or do I need the System.Timers.Timer.Close method, and if it does, where do you call it?

+4
source share
3 answers

After the answers of the_joric and JaredPar and performing profiler tests, which showed that timers hanging around after garbage collection were kicked for the reason that they got stuck around because there is a link to an event handler sticking around. See this for a more detailed explanation.

The real answer is that it is a memory leak if the timer is not closed in the past event handler.

I’ll just show that, although I trust the answers to SO (maybe too much) from the great contributors, they can turn off a bit.

+2
source

No, this will not cause a memory leak. In fact, as your code is written, it does not guarantee proper execution. Timers.Timer is actually just a wrapper on top of Threading.Timer , and it is explicitly listed as being compiled, even if it is currently running.

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

You are not referencing it here, and therefore the very next GC can assemble it while your form is still running, and before the event ever fires

EDIT

The documentation for Timers.Timer seems to be incorrect. A Timer instance will not be compiled if it is not found. He will really 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(); 
+5
source

They will be collected after the method is abandoned. TimerElapsed will either be called, or not depending on when the Timer is completed. Most likely, he will be dead long before 1 second passes.

When you call Timer.Close() , you call Timer.Dispose() , which releases the timer from the timer queue, in which case TimerElapsed will not be called (of course, if it has not already been called).

If you leave the timer open, the GC will call eventaully call Finalize() , which in turn will call Dispose() . But there will be no exact knowledge when this will happen :)

See below for an example, Console.Out.WriteLine("called!!!") will never execute:

 using (System.Timers.Timer NewTimer = new System.Timers.Timer()) { NewTimer.AutoReset = false; ElapsedEventHandler TimerElapsed = (sender, args) => { Console.Out.WriteLine("called!!!"); }; NewTimer.Elapsed += new ElapsedEventHandler(TimerElapsed); NewTimer.Interval = 1000; NewTimer.Start(); } Thread.Sleep(3000); 
+2
source

Source: https://habr.com/ru/post/1397639/


All Articles