So I've been getting my teeth into UWP and developing a simple app in C# using VS2017 v15.6.4, on the latest release of Windows 10.
When running the app I notice its memory usage continues to increase over time.
After a lot of pairing back of the code, I've come to the conclusion that this is being caused by page navigation calls, such as:
Frame.Navigate(typeof SomePage);
Frame.GoBack();
Frame.GoForward();
It is very easy to create and observe this process...
1) In VS2017, create a new Blank App (Universal Windows) project, call it PageTest.
2) Add a new Blank Page to the project, naming it 'NewPage'.
3) Add the following code to the MainPage.xaml.cs:
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace PageTest
{
public sealed partial class MainPage : Page
{
DispatcherTimer timer = new DispatcherTimer();
public MainPage()
{
InitializeComponent();
timer.Interval = TimeSpan.FromSeconds(.01);
timer.Tick += Timer_Tick;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
timer.Start();
}
private void Timer_Tick(object sender, object e)
{
timer.Stop();
Frame.Navigate(typeof(NewPage));
}
}
}
4) Add the following (almost identical) code to NewPage.xaml.cs:
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace PageTest
{
public sealed partial class NewPage : Page
{
DispatcherTimer timer = new DispatcherTimer();
public NewPage()
{
InitializeComponent();
timer.Interval = TimeSpan.FromSeconds(.01);
timer.Tick += Timer_Tick;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
timer.Start();
}
private void Timer_Tick(object sender, object e)
{
timer.Stop();
Frame.Navigate(typeof(MainPage));
}
}
}
You can see that this simple test app contains 2 pages, and when it runs, the app will automatically navigate between the two pages at the rate of 100 times per second (via the timers) until you close the app.
5) Build and run the app. Also run Task Manager and note the app's initial memory footprint.
6) Go and make a cup of coffee. When you come back you'll see the memory usage has grown. And it will continue to grow.
Now I know this example is unrealistic, but it is here purely to demonstrate what I suspect is a fundamental problem affecting most (if not all) UWP apps.
Try this...
Run the Windows 10 Settings app (a UWP app developed by Microsoft). Again, note it's initial memory footprint in Task Manager. (On my kit this starts at about 12.1 MB).
Then repeatedly click on the System Settings icon... then the Back button... then the System Settings icon... then the Back button... You get the idea. And watch the memory footprint also increase.
After a few minutes of doing this, my MS Settings app memory consumption went up to over 90 MB.
This memory consumption seems to be related to UWP page complexity and it goes up rapidly if you start adding a lot of XAML controls to your pages, especially Image controls. And it doesn't take long before my feature rich UWP app is consuming 1-2GB memory.
So this 'problem' seems to affect all frame based UWP apps. I've tried it with other UWP apps on 3 different PC's and I see the same problem on them all.
With my feature rich app, memory consumption has got so bad that I'm now considering scrapping Page navigation altogether and putting everything on the MainPage. Which is not a pleasant thought.
Potential Solutions That Don't Work...
I've come across other articles describing a similar issue and there are proposed solutions that I've tried, which don't make any difference...
1) Adding either of the following lines to the .xaml page definitions does not help...
NavigationCacheMode="Required"
NavigationCacheMode="Enabled"
2) Manually forcing garbage collection when switching pages does not help. So doing something like this makes no difference...
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
GC.Collect();
}
Does anyone know if there a solution to this, or is it a fundamental issue with UWP apps?