Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Garbage collection of C# object declared in constructor

In the following code, I create a DispatcherTimer in the class's constructor. No one keeps reference on it.

In my understanding, the timer should be reclaimed by the garbage collector some time after leaving the constructor's scope. But that doesn't happen! Even after forcing a garbage collection with GC.Collect()

What is going on under the hood?

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        new DispatcherTimer
        {
            Interval = TimeSpan.FromMilliseconds(100),
            IsEnabled = true
        }
        .Tick += (s, e) =>
        {
            textBlock1.Text = DateTime.Now.ToString();
        };
    }
}
like image 702
tpol Avatar asked Aug 31 '11 14:08

tpol


3 Answers

Timers are rather special since they root themselves by calling

this.timerRoot = GCHandle.Alloc(this);

some links

  • Timer, event and garbage collection : am I missing something?
  • Event handler and memory leaks
  • http://blogs.msdn.com/b/abhinaba/archive/2009/05/05/memory-leak-via-event-handlers.aspx

EDIT:

Didn't realize that it was a DispatcherTimer - that doesn't root itself directly but indirectly (to the Dispatcher) which in turn leads to the same effect...

like image 140
Yahia Avatar answered Sep 26 '22 17:09

Yahia


When you just construct the a DispatcherTimer, nothing prevents it from be GCed. However, you set IsEnabled = true, which will call Start() on the timer. When that, happens, this line of code will be executed:

this._dispatcher.AddTimer(this);

And now the Dispatcher itself is rooting the timer, meaning it can't be GCed.

like image 29
dlev Avatar answered Sep 26 '22 17:09

dlev


It will be added to the Dispatcher queue which will be rooted.

like image 34
jason Avatar answered Sep 24 '22 17:09

jason