我花了很多时间试图在 Android 上的 Xamarin.Forms 应用程序中追踪内存泄漏。在经历了很多死胡同和虚假黎明之后,我想我可能遇到了导致问题的东西。
使用 Xamarin Profiler,我可以看到,一旦我创建了一个 Style 并将其应用于控件(或者实际上只是一个隐式样式),我们就会得到 Multiple WeakReferences 保持“活动” - 即没有垃圾收集。
请注意,我假设它们引用的对象已被 GC 处理(因为对对象的引用是weak),但 WeakReferences本身仍然存在。
现在当然 WeakReferences 很小,我知道 - 但是当您在页面推送/弹出的每次迭代中创建数百个时,内存就会增加,我们就会有严重的泄漏。
这是详细信息。使用 Xamarin.Forms 2.3.4.270(我们尚未升级,因为我们想保留已知问题!)在 Android - 物理设备上运行。
应用程序.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 个弱引用。深入了解这些节目:
有趣的是,这些 WeakReference 似乎是作为 Behavior 和 Trigger 附加的一部分创建的。查看顶部的调用树给出:
因此,WeakReference 似乎是作为设置 BindableObject 的值和样式的后续设置的一部分而创建的。
而且似乎 WeakReference 仍在内存中并被某些东西引用 - 行为集合?
使用 Profiler,我可以看到我们没有剩余未 GC 的标签。它似乎在主题/行为/触发器处理中。
我还没有查看 GitHub 上的 Xamarin.Forms 代码 - 这可能是我的下一步行动。
有没有人观察到这一点或得到解决方案?