Memory leaks 表单样式导致WeakReference泄漏

Memory leaks 表单样式导致WeakReference泄漏,memory-leaks,xamarin.forms,weak-references,xamarin.forms-styles,Memory Leaks,Xamarin.forms,Weak References,Xamarin.forms Styles,我已经花了很多时间试图追踪Android上Xamarin.Forms应用程序中的内存泄漏。在经历了许多死巷和虚幻的黎明之后,我想我可能遇到了导致问题的原因 使用Xamarin Profiler,我可以看到,只要我创建一个样式并将其应用于控件(或者实际上只是一个隐式样式),我们就会得到多个WeakReference仍然是“活动的”——即,没有垃圾收集 注意,我假设它们所引用的对象已经被GC’d(因为对该对象的引用很弱),但是weakreference本身仍然存在 当然,我知道weakreferen

我已经花了很多时间试图追踪Android上Xamarin.Forms应用程序中的内存泄漏。在经历了许多死巷和虚幻的黎明之后,我想我可能遇到了导致问题的原因

使用Xamarin Profiler,我可以看到,只要我创建一个样式并将其应用于控件(或者实际上只是一个隐式样式),我们就会得到多个WeakReference仍然是“活动的”——即,没有垃圾收集

注意,我假设它们所引用的对象已经被GC’d(因为对该对象的引用很弱),但是weakreference本身仍然存在

当然,我知道weakreference很小,但是当你在页面推/弹出的每次迭代中创建了数百个时,内存就会累积起来,我们就有了一个严重的漏洞

详情如下。 使用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个weakreference。深入研究这些问题表明:

有趣的是,这些弱引用似乎是作为行为和触发器连接的一部分创建的。查看顶部的调用树可以得出:

因此,WeakReference似乎是在设置BindableObject的值和样式的后续设置时创建的

而且WeakReference似乎仍在内存中,并被某个东西引用—行为集合

使用探查器,我很高兴可以看到我们没有保留未GC的标签。这似乎是主题/行为/触发器处理中的某些内容

我还没有看过GitHub上的Xamarin.Forms代码——这可能是我的下一步行动


是否有人注意到了这一点或找到了解决方案?

我不确定控件的隐式样式,但对于显式样式,您可以在页面超出范围或消失时删除它们

例如,我们对按钮应用了显式样式

<Button x:Name="btnSave" Style="{StaticResource SaveButtonStyle}" Content="Save"/>

protected override void OnDisappearing()
{
    btnSave.Style = null;

    base.OnDisappearing();
}

受保护的覆盖无效OnDisappearing()
{
btnSave.Style=null;
base.OnDisappearing();
}
触发器和行为也可以这样做(您可以清除它们)


我认为对于隐式风格,只有在框架代码中才有一些东西。我们无法确定控件的默认样式是如何与控件作为默认样式连接的。

谢谢-我已尝试将样式设置为null,正如您所说,这可以修复显式样式,而不是隐式样式。清除行为和触发因素并没有帮助。我已经将其标记为有用,但恐怕不是一个答案,因为它不能完全回答这个问题。(顺便问一下,在你发布之前,我已经考虑并尝试了你的建议)。你有没有找到解决这个问题的方法?我想你用的是freshmvvm。这也可能是原因