首页 > 解决方案 > Xamarin.Forms 内存泄漏;GC 没有收集所有东西

问题描述

我看到对此有很多问题,我的印象是处理内存泄漏的每种情况都需要一种独特的解决/跟踪泄漏的方法。所以,在我为多余的职位道歉的情况下支付它。如果有人看到另一篇回答我将描述的问题的帖子,请在评论中添加。

目前,我的问题在所有 xamarin 表单平台(iOS、android、uwp)上仍然存在。

该应用程序的想法是成为一个使用不同图形、图像等旋转的仪表板。在计时器上。每隔 20 秒,应用程序就会切换到一组要显示的新数据。正如您所想象的,这很快就开始显示内存泄漏随着每一页的出现而累积。我将每个类都设为 iDisposeable 并清除了 itemSources/dataSources、我可以的任何数据绑定,并从代码隐藏中调用了 GC。每次页面消失时,我都会破坏一切。Grids,Grid children,页面上使用的任何控件,我将其设置为 null 或清除子项。这似乎并没有得到一切。

我的主要问题是是否有办法为 ContentViews 访问这些根元素,这样我就不必担心杀死页面中呈现的每个控件,而是杀死页面本身。这样,当新页面出现时,旧页面就会被破坏 - 理想情况下释放创建页面时构建的内存。

希望读到这篇文章的人都能明白这一点。放一个这样的代码示例有点困难。我可以从 VS 截取内存分析器或 xamarin 分析器的屏幕截图,但我认为如果你理解这个问题 - 你就会知道发生了什么。如果没有,请告诉我,我会尽可能详细说明。

亲切的问候!

我在下面添加了该应用程序正在做什么的基本概念。

   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
}

标签: c#xamarin.formsmemory-managementmemory-leaksgarbage-collection

解决方案


推荐阅读