Techniques for memory analysis of Windows Phone apps
This article provides an overview of the techniques available for analysing the memory use of Windows Phone apps.
See Also
- Working with Windows Phone devices with 256 MB of memory
- Best practice tips for delivering apps to Windows Phone with 256 MB
- Techniques for memory analysis of Windows Phone apps
- Opting your app out from Windows Phone with 256 MB
- Video playback guidance for Nokia Lumia 610
- Windows Phone Developer Blog (Performance)
Article Metadata
Tested with
Compatibility
Article
Contents |
Windows Phone Memory Profiler
Run the Windows Phone Memory Profiler to get a time-axis graph of application memory consumption, a breakdown of important events (garbage collection, image creation, etc.), and get automated analysis of your application's memory use. The profiler is included in the Windows Phone SDK 7.1 and is available for use with all versions of Visual Studio.
The following section describes a simple test app that we can use to allocate and deallocate memory during profiling, followed by a section showing how the Memory profiler is used.
Sample app for testing memory analysis
To demonstrate how the profiler works we first create a sample Windows Phone 7 app that allocates and deallocates 5MB of memory at a time. This sample application is used throughout the article to demonstrate the different memory analysis techniques.
Create a new Windows Phone 7.5 project after installing the Windows Phone SDK 7.1.1. Open up MainPage.xaml and replace existing “ContentPanel” with a stackpanel and 2 buttons.
<!--ContentPanel - place additional content here-->
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Button Content="Add 5MB" Click="Add_Click" />
<Button Content="Remove 5MB" Click="Remove_Click" />
</StackPanel>
Next, implement the event handlers in MainPage.xaml.cs to allocate and deallocate 5MB of memory.
List<Byte[]> inMemoryCache = new List<byte[]>();
private void Add_Click(object sender, RoutedEventArgs e)
{
inMemoryCache.Add(new Byte[1024 * 1024 * 5]);
}
private void Remove_Click(object sender, RoutedEventArgs e)
{
if (inMemoryCache.Count > 0)
inMemoryCache.RemoveAt(inMemoryCache.Count - 1);
GC.Collect();
}
Profiling
In order to start memory profiling:
- Open the top Debug menu item and choose Start Windows Phone Performance Analysis.
- Once the app is running click the Add 5MB button a few times
- Then select Stop Profiling
You can see the app’s memory allocation graph and markers for when garbage collection took place. Select the time span you’re interested in and select Start Analysis.
The analysis of the selected time span shows that too many Byte[] have been allocated. We can also examine the Heap Summary as was suggested and see a summary of the Silverlight/CLR memory allocation state.
We can even drill all the way down to see how many Byte[] were allocated during this time and their total allocated size %.
You can also use Windows Phone 7 Performance Analysis for CPU profiling. For more information see How to: Capture and Analyze Performance Data Using Windows Phone Performance Analysis (MSDN).
Add on-screen coding4fun <MemoryCounter />
Use the <MemoryCounter /> control in the Microsoft coding4fun Windows Phone Toolkit to display the current memory use and peak memory while developing your app.
Start by adding the Coding4fun assembly to the project. The coding4fun website has instructions on how to add the correct DLLs to your project either by adding references or by using NuGet.
After adding the Coding4Fun.Phone.Controls assembly reference to your project (and unblocking it if needed) you can now add a <MemoryCounter /> to your page.
<!--ContentPanel - place additional content here-->
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Button Content="Add 5MB" Click="Add_Click" />
<Button Content="Remove 5MB" Click="Remove_Click" />
</StackPanel>
<coding4fun:MemoryCounter
xmlns:coding4fun="clr-namespace:Coding4Fun.Phone.Controls;assembly=Coding4Fun.Phone.Controls"/>
The screenshots below show the above code running in our sample test app. Note how the total and peak memory changes when the users clicks the Add 5mb and Remove 5mb buttons.
Create your own memory profiler
Windows Phone provides low level reporting properties that you can use to create your own "pseudo" memory profiler. This might be useful if you want to get memory profiling logs from consumer devices.
The DeviceStatus class has four of the properties needed:
namespace Microsoft.Phone.Info
{
public static class DeviceStatus
{
public static long ApplicationCurrentMemoryUsage { get; }
public static long ApplicationPeakMemoryUsage { get; }
public static long ApplicationMemoryUsageLimit { get; }
public static long DeviceTotalMemory { get; }
}
}
In addition, in the Windows Phone 7.5 upgrade you can call DeviceExtendedProperties.GetValue("ApplicationWorkingSetLimit") to get the memory working set limit for the current device.
An example pseudo memory profiler is given below. This creates an asynchronous timer that records memory conditions and writes them to a report in an IsoStore every 2 seconds. In an ideal world the example would write the report in IsoStore to a web service next time the app restarts - for the sake of brevity this code is omitted.
public static class LowMemoryHelper
{
private static Timer timer = null;
public static void BeginRecording()
{
// before we start recording we can clean up the previous session.
// e.g. Get a logging file from IsoStore and upload to the server
// start a timer to report memory conditions every 2 seconds
timer = new Timer(state =>
{
// every 2 seconds do something
string report =
DateTime.Now.ToLongTimeString() + " memory conditions: " +
Environment.NewLine +
"\tApplicationCurrentMemoryUsage: " +
DeviceStatus.ApplicationCurrentMemoryUsage +
Environment.NewLine +
"\tApplicationPeakMemoryUsage: " +
DeviceStatus.ApplicationPeakMemoryUsage +
Environment.NewLine +
"\tApplicationMemoryUsageLimit: " +
DeviceStatus.ApplicationMemoryUsageLimit +
Environment.NewLine +
"\tDeviceTotalMemory: " + DeviceStatus.DeviceTotalMemory + Environment.NewLine +
"\tApplicationWorkingSetLimit: " +
DeviceExtendedProperties.GetValue("ApplicationWorkingSetLimit") +
Environment.NewLine;
// write to IsoStore or debug conolse
Debug.WriteLine(report);
},
null,
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(2));
}
}
// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
LowMemoryHelper.BeginRecording();
}
The output of the sample test app after a user as selected the Add 5MB button a few times is shown below. We can see that the memory conditions debug output reflects those changes.
Run the Windows Phone Marketplace Test Kit
The Windows Phone SDK 7.1's Windows Phone Marketplace Test Kit includes a Peak Memory Consumption test which monitors whether the total peak memory for an app is under 90 MB. While we highly recommend running the Marketplace Test Kit on your app prior to marketplace submission, the tests are also useful during earlier stages of development.
To run the tests:
- Right click on your project in Solution Explorer and choose Open Marketplace Test Kit.
- Under Monitored Tests you'll see the Peak Memory Consumption test.
- Click Start Application to run the test
- Test all app functionality
- Click Close Application to complete the test.
If your application uses more than 90MB at any point a test failure will be reported, as shown in the screenshot below.
For more information on the Marketplace Test Kit and memory testing see Get Your Windows Phone Applications in the Marketplace Faster (Cheryl Simmons) and Windows Phone Marketplace Test Kit (MSDN).
Check the AppHub crash reports
Whenever a deployed app crashes on a consumer device, a crash report is sent back to AppHub. An OutOfMemoryException in an AppHub crash report indicates that your app has a memory problem that should be fixed.
You can inspect crash reports for your apps through your AppHub account, filtering reports to only display crashes in a specific date range. The reports include information about what exceptions have occurred, and in what functions, along with a stack trace of the function calls that lead up to them. As an example, the screenshot below shows a real report for an OutOfMemoryException that occurred 18 times in the field along with the associated stack trace.
However if you see errors, they are indicative that more work is needed!









