I see there are a lot of questions on this, and I am under the impressions that each situation of handling a memory leak needs a unique way of solving/tracking down the leak. So, paying it forward on my apology for the redundant post. If anyone sees another post that is answering the questions I will describe, then please add it in the comments.
At the moment my problem persists on all xamarin forms platforms (iOS, android, uwp).
The idea of the app is to be a dashboard that rotates with different graphs, images, ect. on a timer. Every 20 seconds the app switches to a new set of data to be displayed. As you can imagine this quickly started to show the memory leak building up as each page appeared. I made every class a iDisposeable and cleared the itemSources/dataSources, any data bindings that I could, and called the GC - from the codebehind. Everytime a page dissappears, I deystroyed everything. Grids, Grid children, any control that was used on the page I set it to null or clear the children. This just does not seem to get everything.
My main question is if there is a way to reach these root elements for the ContentViews, this way I do not have to worry about killing every control that is rendered in the page, but rather kill the page itself. This way as the new page appears, the old one is deystroyed - Ideally releasing the memory built from creating the page.
Hopefully whomever reads this will get the picture. It is a little hard to put a code example of this up. I could take screen shots of the memory analyzer or xamarin profiler from VS, but I think if you understand the issue - you have an idea of what is happening. If not please let me know and I will elaborate as much as possible.
Kind Regards!
I have added the basic idea of what the app is doing below.
public class PagesListVM
{
private int _intXValueg;
private int _intYValue;
private string _strTemplate;
public int XValue
{
get { return _intXValueg; }
set { _intXValueg = value; }
}
public int YValue
{
get { return _intYValue; }
set { _intYValue = value; }
}
public string templateView
{
get { return _strTemplate; }
set { _strTemplate = value; }
}
}
public class PagesMgr
{
//other delegates for events from manager and DisplayPage defined here
private List<PagesListVM> _objPagesList = new List<PagesListVM>();
public List<PagesListVM> PagesList
{
get
{
return _objPagesList;
}
set
{
_objPagesList = value;
}
}
public void getPageValues()
{
//sql to get the pages x and y values . Different pages are having different vms.
//return value gets set to PagesList.
}
}
public partial class MainDisplayPage : ContentPage
{
private PagesMgr _objMgr = null;
public MainDisplayPage(PagesMgr objMgr)
{
// InitializeComponent();
//mgr is passed in when this main page is called
_objMgr = objMgr;
}
private void DisplayPage_Disappearing(object sender, EventArgs e)
{
//close events
}
private void DisplayPage_Appearing(object sender, EventArgs e)
{
if (_objMgr != null)
{
//events from the manager to start the loop for the pages, data fetching, ect..
_objMgr.getPageValues();
StartPageLoop();
}
}
public void StartPageLoop()
{
foreach (PagesListVM page in _objMgr.PagesList)
{
//check the list and then if the template is the content view you want to show for that data display the content view inside the page.
if (page.templateView == "PageOneView")
{
//show the content view page in a grid on this main display page and pass the _objMgr to the contentview.
}
//the timer runs the page for given amount of seconds and then closes the content view and shows the next one. (show/hide)
//here is where I would like to know how to kill the contnent view. we have charts and graphs and matrixes we show on all the
//content views, and well I have tried to dispose of all the children, and bindings in the view when we leave it as I can descibed above.
}
}
}
public partial class PageOneView : ContentView, IDisposable
{
private bool disposedValue;
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects)
}
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
disposedValue = true;
}
}
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
// all the controls are here
//I have tried clearing all the bindings and item sources / calling the Dispaose method on the page when it appears and when it leaves
//and the controls on this page continue to increase the memory each time they are rendered with new data.
//but I think it is better to kill the view entirely in the MainDisplayPage when the next view appears or when the timer for this view runs out
somecontrol.ItemSource = _objMgr.DataForThisPageVm
}