UWP Windows 10 应用程序内存在导航时增加

Posted

技术标签:

【中文标题】UWP Windows 10 应用程序内存在导航时增加【英文标题】:UWP Windows 10 App memory increasing on navigation 【发布时间】:2016-02-29 11:29:48 【问题描述】:

我有一个 UWP Windows 10 应用程序,并注意到任务管理器中的内存使用量随着时间的推移而增加。

我剥离了应用程序,发现导航页面时内存正在增加。所以我做了一个简单的应用程序,只有几页来测试,这个简单的应用程序的内存仍在增加。我有一个 MainPage 将框架从 Page1 导航到 Page2 并返回计时器。

    public sealed partial class MainPage : Page


    private DispatcherTimer _timer;

    private bool _page1Showing;
    private bool _timerRunning;

    public MainPage()
    
        this.InitializeComponent();

        _timer = new DispatcherTimer();
        _timer.Interval = new TimeSpan(0, 0, 0, 0, 200);
        _timer.Tick += _timer_Tick;
    

    private void _timer_Tick(object sender, object e)
    
        GC.Collect();

        this.rootFrame.BackStack.Clear();
        this.rootFrame.ForwardStack.Clear();

        if (_page1Showing)
        
            this.rootFrame.Navigate(typeof(Page2));
            _page1Showing = false;
        
        else
        
            this.rootFrame.Navigate(typeof(Page1));
            _page1Showing = true;
        
    


    private void Button_Click(object sender, RoutedEventArgs e)
    
        if (_timerRunning)
        
            _timer.Stop();
            _timerRunning = false;
        
        else
        
            _timer.Start();
            _timerRunning = true;
        
    


Page1 和 Page2 是带有背景颜色网格的空白页面,因此您可以看到导航。此应用运行时,任务管理器中的内存使用量每 30 分钟增加约 1MB。

我已经使用 VS2015 中的内存诊断运行了应用程序,托管堆符合预期:

堆总是在增加:

比较堆显示的快照:

我很困惑这些 McgInterop 对象是什么?以及为什么这么简单的应用程序的内存使用量总是在增加。我的主要应用程序需要运行很长时间(几个月+)。感谢任何帮助。

我已尝试更改页面 NavigationCacheMode,如果设置为必需,则页面将创建一次。如果设置为禁用,则每次都会创建页面,并且我检查了终结器是否按预期调用。

--

编辑:我添加了一个按钮来启动和停止计时器(更新了上面的内容)。似乎在定时器运行时,任务管理器中的内存使用量会增加,当定时器停止时,内存使用量最终会下降。

我测量了一天中任务管理器中的内存使用情况,大约每 2 小时启动和停止计时器,如下所示,它缓慢增加,然后在某个时间点下降:

12.5 -> 17.1 -> 16.7 -> 13.9 -> 16.8 -> 22.5 -> 13.6 -> 14.6 -> 24.9 -> 15.2

所以我猜一切正常?但我不清楚这里发生了什么,为什么增加这么多?什么时候在什么条件下释放?

页面导航时系统是否延迟释放内存?用户通常何时与屏幕交互?

【问题讨论】:

Frame 保存了导航历史。偶尔清空回栈时,是否还会出现这种情况? 我更新了上面的代码清除了backstack,任务管理器中的内存还是和以前一样增加了。 我写了一个演示(和你的一样),这是内存使用图:the memory is NOT increasing except at the beginning VS2015 with update1。 Windows 10, 10586. 补充: 我想你不必每 200 毫秒调用一次GC.Collect();,系统会为你调用。我的demo已经运行了快2个小时了,内存并没有一直在增加,但是在一点点变化。 这是 Visual Studio 中有关 Memory Tool 的文档链接:blogs.msdn.com/b/visualstudioalm/archive/2013/10/16/… 当您得到解决方案时,请在自我回答中分享。以下答案中的人(已删除)正在要求它。谢谢 【参考方案1】:

每次导航到 Page 时,都会创建一个新的 Page 实例,但不会释放前一个 Page(即使该 Page 已经在导航堆栈中)。

为防止同一页面的多次分配,请将NavigationCacheMode="Enabled"属性设置为页面。

另外,为了最小化内存分配,您必须覆盖方法OnNavigatedToOnNavigatedFrom

OnNavigatedTo 方法中:

实例化所有内存密集型对象或资源 添加您需要的所有事件处理程序 启动所有计时器、任务或线程

OnNavigatedFrom:

释放所有资源 停止所有计时器、任务或线程 删除所有重物的引用 删除所有事件处理程序 仅当您确实需要时,才调用 GC.Collect()

【讨论】:

来自我的问题:我尝试更改页面 NavigationCacheMode,如果设置为必需,则页面创建一次。如果设置为禁用,则每次都会创建页面 @tagy22 如果您使用 required,您可能会出现内存不足的风险,启用操作系统仅在可能的情况下缓存页面。禁用后,操作系统应在内存不足之前自动解除分配实例以释放内存,但根据我的经验,它效果不佳。此外,如果您使用缓存,则必须在“OnNavigatedFrom”上处理资源,例如,您可以处理 Timer 而不是停止它。【参考方案2】:

我们可以查看您的 xaml 代码吗?您是否在 xaml 中使用 x:name 并且它被破坏了?如果是这样,那可能会导致您的内存泄漏。

如果您使用 x:name,请查看此链接: http://support.scichart.com/index.php?/News/NewsItem/View/21/wpf-xname-memory-leak--how-to-clear-memory-in-scichart

当然,UWP 可能会以不同的方式处理 x:name...

【讨论】:

【参考方案3】:

我在 w8.1 上看到了同样的问题,printingInline 使用 charmBar 在应用程序崩溃 (1.5 GB) 之前会消耗大量内存。但通常你不需要 GC.colect() 它会自动工作。

【讨论】:

以上是关于UWP Windows 10 应用程序内存在导航时增加的主要内容,如果未能解决你的问题,请参考以下文章

处理返回导航 Windows 10 (UWP)

Xamarin UWP + Android ContentPage 导航 PushAsync

Windows 10 UWP:无法停止枢轴控制循环

在 UWP 中拖动面板

Windows 10 UWP 应用程序在启动时崩溃(错误模块名称:Windows.UI.Xaml.dll)

微软UWP应用,导航栏设计。