我一直在花费很多时间追踪我们的Xamarin.Forms应用程序在Android上的内存泄漏问题。经过许多盲目的尝试和失败的尝试后,我认为我可能找到了导致问题的原因。
使用Xamarin Profiler,我可以看到当我创建一个Style并将其应用于控件(或实际上只是一个隐式样式)时,我们会得到多个WeakReferences保持“活动状态” - 即未垃圾收集。
请注意,我假设它们所指向的对象已经被GC'd(因为对对象的引用是弱引用),但是WeakReferences 本身仍然存在。
现在当然我知道WeakReferences很小 - 但是当你每次迭代页面推入/弹出时都创建了数百个,那么内存就会增加,我们就会有一个显着的泄漏。
以下是详细信息。 使用Xamarin.Forms 2.3.4.270(我们没有升级,因为我们想保持已知的问题!) 在Android上运行 - 物理设备。
App.xaml:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:ProfiledFormsApp2;assembly=ProfiledFormsApp2"
x:Class="ProfiledFormsApp2.App">
<Application.Resources>
<ResourceDictionary>
<Style TargetType="Label">
<Setter Property="FontSize" Value="Large" />
<Setter Property="TextColor" Value="Blue" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
页面XAML:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage Title="Plain Page" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="ProfiledFormsApp2.PlainPage">
<ContentPage.Content>
<StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Core Navigation"/>
<Label Text="Number of items:" />
<Label Text="{Binding ItemsCount}" />
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
当我导航到上述页面并返回 3 次时,我们创建了以下 WeakReference(及相关)类 - 下面的屏幕截图来自 Profiler 快照。
请注意,我们有55个WeakReferences。深入挖掘这些内容会显示:
有趣的是,这些WeakReferences似乎是作为行为和触发器附加的一部分而创建的。查看顶部的调用树如下:
因此,WeakReference似乎是作为设置BindableObject值及随后设置样式的一部分而创建的。
同时,它似乎仍然在内存中,并且被某个东西引用 - 行为集合?
使用Profiler,我可以看到我们没有留下未GC'd的标签。似乎是主题/行为/触发器处理中的某些东西。
我还没有查看GitHub上的Xamarin.Forms代码 - 那可能是我的下一步行动。
有人观察到此问题或有解决方案吗?