Утечка памяти Xamarin при обмене страницами - PullRequest
0 голосов
/ 14 мая 2019

У меня много трудностей с утечками памяти при использовании Xamarin.Есть один набор, с которым я особенно борюсь.Чтобы проиллюстрировать эту утечку, я создал простейшую из возможных программ, которая просто переключается между двумя страницами.Код выглядит следующим образом:

App.xaml.cs:

    using System;
    using Xamarin.Forms;
    using Xamarin.Forms.Xaml;
    using System.Diagnostics;

    [assembly: XamlCompilation(XamlCompilationOptions.Compile)]
    namespace MemoryLeak
    {
        public partial class App : Application
        {
            public static App m_app;

            MainPage[] pages = new MainPage[2];

            public void SetPage(int idx)
            {
                MainPage page = pages[idx % 2];

                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
                Debug.WriteLine(string.Format("{1}:mem={0}", System.GC.GetTotalMemory(true), idx));

                page.ShowMemoryUse();

                MainPage = page;
            }

            public App()
            {
                InitializeComponent();

                m_app = this;

                pages[0] = new MainPage(0);
                pages[1] = new MainPage(1);

                SetPage(0);
            }

            protected override void OnStart()
            {
                // Handle when your app starts
            }

            protected override void OnSleep()
            {
                // Handle when your app sleeps
            }

            protected override void OnResume()
            {
                // Handle when your app resumes
            }
        }
    }

MainPage.xaml:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:MemoryLeak"
                 x:Class="MemoryLeak.MainPage">

        <StackLayout>
            <!-- Place new controls here -->
            <Label x:Name="myText" Text="Welcome to Xamarin.Forms!" 
               HorizontalOptions="Start"
               VerticalOptions="Center"/>
            <Button Text="Next" Clicked="OnButtonClicked" />
        </StackLayout>

    </ContentPage>

MainPage.xaml.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Xamarin.Forms;
    using System.Diagnostics;

    namespace MemoryLeak
    {
        public partial class MainPage : ContentPage
        {
            int m_id;

            public MainPage(int id)
            {
                InitializeComponent();

                m_id = id;
            }

            public void ShowMemoryUse()
            {
                myText.Text = string.Format("{1}: {0}", System.GC.GetTotalMemory(true), m_id);
            }

            void OnButtonClicked(object sender, EventArgs args)
            {
                App.m_app.SetPage(m_id == 0 ? 1 : 0);
            }
        }
    }

Теперь, если я запускаю эту программу под UWP и нажимаю несколько раз на кнопку «Далее», я вижу, что использование памяти увеличивается без границ.Если я использую Performance Profiler, я также вижу множество объектов, которые никогда не освобождаются.Например, 40-кратное нажатие кнопки «Далее» приводит к появлению следующих объектов:

  • PropertyChangedEventHandler - создано 95 экземпляров
  • EventHandler - создано 94 экземпляра
  • ConditionalWeakTable -Создано 72 экземпляра
  • Контейнер - создано 72 экземпляра
  • Xamarin.Forms.Platform.UWP.PageRenderer [RCW] - создано 41 экземпляр
  • Xamarin.Forms.Platform.UWP.BackgroundTracker - создано 41 экземпляр
  • RuntimeType - создано 360 экземпляров

И многие другие.

Я не вижу, что я делаю здесь неправильно.Это проблема с Xamarin?Разве я не должен обмениваться страницами, ссылаясь на «MainPage»?

Спасибо.

...