У меня много трудностей с утечками памяти при использовании 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»?
Спасибо.