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"
属性设置为页面。
另外,为了最小化内存分配,您必须覆盖方法OnNavigatedTo
和OnNavigatedFrom
。
在OnNavigatedTo
方法中:
在OnNavigatedFrom
:
【讨论】:
来自我的问题:我尝试更改页面 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 应用程序内存在导航时增加的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin UWP + Android ContentPage 导航 PushAsync