Windows Phone 8: LongListSelector Memory Leak

Disclaimer!:  I am not a Window Phone Expert though dabble occasionally… 

Summary

The clean-up for the Windows Phone LongListSelector control on Windows Phone 8 often does not recover a relatively large amount of memory that the control has been using.  Some/much of the lost memory can be recovered as shown below.

Scenario

I was writing a language learning app and had a page that contained a Pivot control with half a dozen PivotItems.  Most of these PivotItems contained a LongListSelector.  This page was typically loaded many times during typical use of the app.  Memory use was observed to rapidly grow to 150MB and more, despite only text – no images or other media – being used.

Investigation

I extracted a small but representative sample of the offending code into a separate app to investigate.  This can be downloaded here.

The start screen is below.  The check box allows my fix/workaround to be switched on/off.

20140124-05

To demonstrate the issue, don’t tick the checkbox.  Click start.

The next screen is a sample screen from my language app, filled with random dummy data.  In my app, this screen is used often in between various other screens.  To simulate this, I clicked the “Next” button 30 times (the page URL contains a dummy random parameter to ensure it reloads each time).  At the end of this, the phone shows memory use has increased rapidly:

20140124-01

For good measure, I added a button to force a full, blocking garbage collection.  This recovered a small amount of memory:

20140124-02

Clearly, nearly 100MB with only small amounts of text and no use of images/sound/video is quite excessive.

The memory use over the lifetime of the text was captured in the Memory Profiler:

20140124-06

It is worth noting that the total memory captured in the Memory Profiler was only 13MB.  This can be downloaded here.

Clearly there is a large discrepancy between the 13MB total being reported in the profiler and the nearly 100MB use observed.  The profiler doesn’t cover system memory, which got me thinking that something within one of the native controls could be the cause.

It is worth noting that I was already removing the page from the Back Stack and I had verified that the page was being cleaned up by putting a debug statement in the page destructor.  So, although the clean-up was happening in theory, it certainly wasn’t cleaning up everything.

Workaround / Fix

After some trial and error improvement, I found an approach that was able to recover most/all of the memory that was being lost.  This involved clearing all of the values of the dependency properties on the LongListSelector controls (and the Pivot control too).  A snippet of the code is given at the bottom of this post.

I am not sure if this is widely regarded as normal practice.  It did not seem obvious to me.

Running the test app again, this time with the Cleanup checkbox ticked:

After the 30 pages:

20140124-03

After forcing a garbage collection:

20140124-04

Clearly, significantly better.  Also reflected in the Memory Profile:

20140124-07

Code Sample

The workaround/fix makes use of the DependencyObject.ClearValue method:

20140124-08

20140124-09

The full source code can be found in the sample project.  The workaround/fix is located around line 105 in PivotPage.xaml.cs

This does seem rather an ugly brute force fix and perhaps others are possible.  But sometimes you just have to go with what works…

Advertisements

4 comments

  1. Hi all
    I get out of memory exception when set source for LongListSelector (source = TextBlock + Image) firsrt time. How handle it?
    Thanks and Best Regards

  2. If I swipe pivot item quickly and loop many times, it will also cause memory increased rapidly.
    How do I call the clean dependency? Call the clean dependency if pivot changed event was fired then call Populate to rebind dependency? But it seems too slow to rebind dependency?
    Thanks in advanced.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s