【问题标题】:UWP - Frame navigation seems to cause unmanaged memory leaksUWP - 框架导航似乎会导致非托管内存泄漏
【发布时间】:2016-11-18 13:00:44
【问题描述】:

似乎 Frame 导航(特别是 Frame.Navigate(Type) 方法)正在泄漏非托管内存。
每次导航后,当我查看 Visual Studio 诊断工具 时,Private Bytes 都会增加,但是当我拍摄内存快照时,堆大小 em> 没有增加。页面的组件越多,它就越糟糕。记忆似乎永远不会被释放。应用程序是在 Debug 还是 Release 中构建(无论是否带有 .Net Native)都无关紧要。我正在使用 14393 SDK(周年更新)。

我创建了一个示例应用程序,它有一个母版页和 2 个(内容)页面,它在它们之间不断导航(在 PageLoaded 事件上)。我已将 CacheSize="0" 设置为 Frame 并且页面具有 NavigationCacheMode="Disabled" 因此它们不会被缓存。我还在每次导航之前清除后台堆栈并取消订阅 PageUnloaded 上的每个事件。
这是其中一个页面的 .cs 文件:

public sealed partial class FirstPage : Page
{
    public FirstPage()
    {
        this.InitializeComponent();
    }

    private void NavigateToSecondPage()
    {
        MainPage.ContentFrame.BackStack.Clear();
        MainPage.ContentFrame.Navigate(typeof(SecondPage));
    }

    private void NavigateButton_Click(object sender, RoutedEventArgs e)
    {
        NavigateToSecondPage();
    }

    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        if (!MainPage.StopNavigating)
        {
            NavigateToSecondPage();
        }
    }

    private void Page_Unloaded(object sender, RoutedEventArgs e)
    {
        this.NavigateButton.Click -= NavigateButton_Click;
        this.Loaded -= Page_Loaded;
        this.Unloaded -= Page_Unloaded;
    }
}

以及对应的XAML文件:

<Page
    x:Class="LeakTestApp.FirstPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:LeakTestApp"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Loaded="Page_Loaded"
    Unloaded="Page_Unloaded">

    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="First Page" FontSize="32" />
        <Button x:Name="NavigateButton" Content="Navigate to Second Page" Click="NavigateButton_Click" />
        <StackPanel Width="350">
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
            <TextBox />
        </StackPanel>
    </StackPanel>
</Page>

这里的文本框可以更好地显示问题。
您可以看到here,当我开始导航时,Private Bytes 开始迅速增加,但 Heap Size 并没有增加。
启用缓存 (NavigationCacheMode="Required") 或手动调用 GC.Collect() 无济于事。
您可以查看完整的源代码here

我有什么明显的遗漏吗?我没有正确清除所有内容吗?或者也许运行时最终会释放内存?

谢谢

更新:在 cmets 中查找显示该行为的视频(我没有足够的声誉来发布超过 2 个链接)

【问题讨论】:

  • Here(我不能在帖子中发布超过 2 个链接)是两个 Native Heap 快照的比较。由此看来,问题与 XAML 模板和布局有关,而不是 Frame.Navigate
  • 我记录了一个short video,您可以在上面记录我设备上的行为。您还可以看到启用缓存没有帮助。

标签: c# memory memory-leaks uwp


【解决方案1】:

我无法重现您的问题,因为您的项目的监控结果在我这边如下。 我没有在你的照片中看到 gabbge 集合。但在我这边,它有 GC 经常工作。注意 GC 不是实时的。您可以尝试使用GC.Collect Method () 自行收集,但不建议在产品中使用。详情可以参考this thread

【讨论】:

  • 您看不到 GC 收集,因为我发布了 Release 版本的屏幕截图,here 是 Debug 的屏幕截图。我已经能够在多个设备上重现该问题。能否请您再运行几分钟,我想会更容易看到。
  • @Roozi 我很遗憾我仍然无法通过测试几分钟来重现该问题。我会继续测试。还有一件事,请尝试将NavigationCacheMode设置为Required并再次测试。禁用缓存模式不会缓存数据,实际上每次导航到页面都会创建新的实例,这可能会导致内存增加。
  • 这很奇怪。我记录了一个short video,您可以在上面记录我设备上的行为。您还可以看到启用缓存没有帮助。如果我手动 GC.Collect() 没有任何变化,但这是意料之中的,因为分配发生在本机堆上。
【解决方案2】:

我已向 Microsoft 报告了这个问题,实际上存在一个小的内存泄漏,现在应该修复。
然而,我看到这种重大泄漏的原因是 Visual Studio 诊断工具 显示了不正确的值。当我使用 Visual Studio Performance Profiler 时,泄漏要小得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 2012-05-18
    • 2018-10-14
    • 2017-06-20
    • 1970-01-01
    • 2012-01-30
    相关资源
    最近更新 更多