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

我有一个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是带有背景颜色网格的空白页面,因此您可以看到导航。 当这个App运行时,任务管理器中的内存使用量每30分钟增加大约1MB。

我在VS2015中使用内存诊断运行App,托管堆正如预期的那样:

在此处输入图像描述

堆总是在增加:

在此处输入图像描述

比较堆的快照显示:

在此处输入图像描述

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

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

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

我在一天内测量了任务管理器中的内存使用量,并且每隔2小时左右停止计时器,如下所示,它会慢慢增加然后在某个时刻下降:

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

所以我猜一切都运转良好? 但我不清楚这里发生了什么,为什么它会增加这么多? 什么时候在什么条件下免费?

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

我们可以看到你的xaml代码吗? 你在xaml中使用x:name是否被销毁? 如果是这样可能会导致内存泄漏。

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

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

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

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

此外,要最小化内存分配,必须覆盖方法OnNavigatedToOnNavigatedFrom

OnNavigatedTo方法中:

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

OnNavigatedFrom

  • 处置所有资源
  • 停止所有计时器,任务或线程
  • 删除所有重物的引用
  • 删除所有事件处理程序
  • 只有在你真正需要的时候,才能调用GC.Collect()

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