8

It seems that Frame navigation (specifically Frame.Navigate(Type) method) is leaking unmanaged memory.
After every navigation when I look at the Visual Studio Diagnostic Tools, Private Bytes is going up but when I take a snapshot of the memory, the Heap Size isn't increasing. The more components the page has the worse it is. The memory doesn't seem to ever be released. It doesn't matter whether the app is built in Debug or Release (both with .Net Native and without). I'm using the 14393 SDK (Anniversary update).

I've created a sample app that has a master page and 2 (content) pages that it keeps navigating in between (on PageLoaded event). I've set CacheSize="0" to the Frame and Pages have NavigationCacheMode="Disabled" so they don't get cached. I'm also clearing the backstack before every navigation and unsubscribing every event on PageUnloaded.
Here is the .cs file for one of the Pages:

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;
    }
}

And corresponding XAML file:

<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>

The textboxes here are there to better show the problem.
You can see here that as soon as I start the navigation Private Bytes start increasing rapidly but the Heap Size doesn't increase.
Enabling cache (NavigationCacheMode="Required") or manually calling GC.Collect() doesn't help.
You can look at the full source code here.

Is there something obvious I am missing? Am I not clearing everything properly? Or perhaps the runtime will release the memory eventually?

Thank you

Update: Look in the comments for a video showing the behaviour (I don't have enough reputation to post more than 2 links)

Roozi
  • 91
  • 6
  • 1
    [Here](http://i.imgur.com/QuQIaFN.png) (I cannot post more than 2 links in the post) is a comparison of two _Native Heap_ snapshots. From this it looks like the problem has to do with XAML templates and layouts rather than Frame.Navigate – Roozi Nov 18 '16 at 15:14
  • I've recorded a [short video](http://www.screencast.com/t/MrBT1ozgwu) on which you can the behaviour on my device. You can also see that enabling cache didn't help. – Roozi Nov 23 '16 at 16:02

2 Answers2

1

I cannot reproduce your issue since the monitor result of your project is as follows on my side. enter image description here I didn't see the gabbge collection in your picture. But on my side it has GC frequently worked.Pay attention that GC is not in real-time. You can try to use GC.Collect Method () to gabbge collecting by yourself but it is not recommended to use in a product. Details you can reference this thread.

Community
  • 1
  • 1
Sunteen Wu
  • 10,509
  • 1
  • 10
  • 21
  • You cannot see GC colects because I posted a screenshot from Release build, [here](http://i.imgur.com/vjlH4pK.png) is a screenshot from Debug. I've been able to reproduce the issue on multiple devices. Could you please try to run it for a few more minutes, I think it would be easier to see. – Roozi Nov 22 '16 at 09:44
  • @Roozi I'm sad I still cannot reproduce the issue by testing for few minutes. I will go on testing. One more thing, please try to set the `NavigationCacheMode` to `Required` on your side and test again. Disable the cache mode do will not cache data, actually every time you navigate to the page will create new instances which may lead the memory increased. – Sunteen Wu Nov 23 '16 at 01:59
  • That's strange. I've recorded a [short video](http://www.screencast.com/t/MrBT1ozgwu) on which you can the behaviour on my device. You can also see that enabling cache didn't help. If I manually GC.Collect() nothing changes, but that is expected since the allocations happen on the native heap. – Roozi Nov 23 '16 at 15:46
1

I've reported this issue to Microsoft and there was actually a small memory leak that should be fixed now.
However the reason I was seeing this substantial leak is due Visual Studio Diagnostic Tools showing incorrect values. When I used Visual Studio Performance Profiler the leak was much smaller.

Roozi
  • 91
  • 6