Search code examples
c#mvvmmemory-leakswindows-phonedispose

implementing Dispose and Finalize for Windows phone silverlight Pages


I have a big solution with graphics, popups and animations. I have found out that I have a massive memory leak during page navigations.

Tries

I therefore tried with the first solution:

protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        if (App.RootFrame.CanGoBack)
            App.RootFrame.RemoveBackEntry();
        GC.Collect();
        base.OnNavigatedTo(e);
    }

This from several sources on MSDN and Stackoverflow, should remove the memory stored for the page. This was not the case and I am unsure if the MVVM structure of the code somehow keeps information stored. I then tried to implement deconstructors and force values to null when the event was fired like:

~SecondScreen()
    {
        In_Game_Crest = null;
        currentViewModel = null;
    }

This I did for all pages, popups and usercontrols. I then again went through the code using debug, and non of the pages deconstructor was ever fired. This has lead me on to try and use IDisposable and fiddeling around with the viewmodelLocator provided by MVVMLight, without any success.

Investigation

I have read the following addressing the issue: StackOverFlow: Finalizer and Dispose

Finalize/Dispose pattern in C#

MSDN: Implementing a Dispose Method

MSDN: Implementing Finalize and Dispose to Clean Up Unmanaged Resources

Questions

But it has confused me more than it helped me. How should I implement the dispose and finalize methods for a page for my windows phone?

Since I'm using the MVVM structure should these methods be implemented in a ViewModel or behind the given page or both?

Examples for windows phones would be much appreciated.


Initial try with Dispose

I have read some more about the subject and found that the finalize maybe shouldn't be written? But I am still unsure. But based on this and the first MSDN link above, I tried the following:

private bool disposed = false;

    public void Dispose()
    {
        Dispose(true);
        // Take yourself off the Finalization queue 
        // to prevent finalization code for this object
        // from executing a second time.
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
  // Check to see if Dispose has already been called.
  if(!this.disposed)
  {
     // If disposing equals true, dispose all managed 
     // and unmanaged resources.
     if(disposing)
     {
        // Dispose managed resources.
         currentView = null;
         popup = null;
         Image1 = null;
         Image2 = null;
     }
          // Release unmanaged resources. If disposing is false, 
          // only the following code is executed.
          this.Content = null;
          // Note that this is not thread safe.
          // Another thread could start disposing the object
          // after the managed resources are disposed,
          // but before the disposed flag is set to true.
          // If thread safety is necessary, it must be
          // implemented by the client.

  }
  disposed = true;         
    }

    // Use C# destructor syntax for finalization code.
    // This destructor will run only if the Dispose method 
    // does not get called.
    // It gives your base class the opportunity to finalize.
    // Do not provide destructors in types derived from this class.

    ~FirstPage()
    {
        Dispose(false);

    }
    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        this.Dispose();
        base.OnNavigatedFrom(e);
    }

But, but but this just made my memory increase by 23MB when I got to the second screen. This leads me to the question again, how and what should I try to implement, and WHY could the memory increase?

this = null, base.Dispose()

I have seen different implementations, either using this = null in the dispose function or using base.Dispose(). I figure that the latter can only be used if the class is IDisposable? Is this the way to go? If so how do I go about it?

Using Microsoft Profiler

So I used the profiler to verify that the FirstPage is not removed enter image description here From the above Figure it can be seen that the firstpage exists. In the comments I was told to look for the instances and reference to the elements. I therefore chose instances of firstpage and got: enter image description here Here it is confirmed that FirstPage is never destroyed. But I am stuck here, how should I interpret the data? Hoping for some help.


Solution

  • So what I did to solve the page memory leak was using the answer at this question:

    Remove Pages windows phone

    There still exists some leak, which helped when removing the storyboards and eventhandlers, and adding them and removing them. But some memory is still there but no leak is occurring.