Monday, September 20, 2010

Windows Phone Memory Constraints

The final Windows Phone Developer Tools have been released and the launch date is not far away. It's time to finalize the apps.
Windows Phone has some tough hardware requirements, but it's still a mobile platform with limited resources. In this blog post I'll describe how to determine the current memory usage, what the allowed maximum is to get your app approved for the Marketplace and other constraints a developer should be aware of.

Maximum memory usage
The Windows Phone hardware specifications requires that a device has 256 MB RAM or more. The allowed maximum memory an app can use is defined in the Windows Phone 7 Application Certification Requirements at point 5.2.5
The application must not exceed 90 MB of RAM usage. However, on devices that have more than 256 MB of memory, an application can exceed 90 MB of RAM usage.
One might now ask how to get this information at runtime. Fortunately there's the DeviceExtendedProperties class to obtain some device information at runtime. This class defines the GetValue and TryGetValue methods which expect a string key as parameter. The list of available property keys is defined here. Among other interesting properties like the DeviceUniqueId, it's possible to retrieve the DeviceTotalMemory, the ApplicationCurrentMemoryUsage and the ApplicationPeakMemoryUsage. The property keys are interpreted case-sensitive.
The application needs to define the device identity capability in the WMAppManifest.xml file in order to retrieve the DeviceUniqueId property, but it's not needed for the other keys like the ApplicationPeakMemoryUsage.

Here's the code to get the peak memory usage and the available total memory at runtime:

var timer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(2)};
timer.Tick += (s, e) =>
   var memuse = (long)DeviceExtendedProperties.GetValue("ApplicationPeakMemoryUsage");
   var maxmem = (long)DeviceExtendedProperties.GetValue("DeviceTotalMemory");
   memuse /= 1024 * 1024;
   maxmem /= 1024 * 1024;
   MyTextBlock.Text = String.Format("Mem usage: {0} / {1} MB", memuse, maxmem);

The timer checks the properties every two seconds and converts the bytes to MB. The values are then shown in a TextBlock. The peak memory is the most interesting since this value must not exceed 90 MB on a device with 256 MB. Also note that an empty application with two grids and a TextBlock already has a peak of 5 - 7 MB in the emulator or on a device.

PhoneApplicationPage.State limitation
The PhoneApplicationPage.State property is typically used to save transient state for tombstoning. The size of the State data is limited to 2 MB for a Page and 4 MB for the whole application. Be warned, if this limit is reached a not very descriptive exception is thrown. The message text is "The client who called IAccessControl::IsAccessPermitted was the trustee provided tot he method".
If more than 2 / 4 MB is needed to save transient data, the IsolatedStorage can be used. The applications IsolatedStorage is only limited by the device's flash storage size. The minimum requirement for Windows Phone is 8 GB. The available free isolated storage in bytes can be retrieved with the AvailableFreeSpace property of the IsolatedStorageFile class.