I will share with you an experience I had when I was developing an unofficial application for Ferrari. The code is available on Github. I was facing a problem with memory usage in Windows Phone. In the following, I will explain the problem in detail, identify the cause and suggest some solutions.
Insufficient Memory Exception
In some scenarios where I have a good number of images, the OS may handle insufficient memory exception and the application crashes! That was happening on Windows Phone, and not on Windows Store application.
Why is That Happening?
Windows Phone 7 and 8 keep all the downloaded images in cache. In fact, the .jpg or .png images that are some hundreds of KB will be decompressed and so they will have some MB size. Considering that Windows Phone 7 & 8 allow only 150 MB for devices that have 512 MB RAM and 300 MB for devices that have 1 GB RAM. So if you have like 200 images, 1 MB each one after decompression, then you will end end up with application crash, because there's no enough memory space available.
This exception didn't happen in Windows Store application because there's no memory limit of RAM space for each one, unlike Windows Phone.
Some Additional Crashes!
In some other cases, where I have enough memory space and want to navigate to another page, the application crashes. For the second time, this is because there is not enough memory space available!
For this case, what exactly happened is that the application is navigating from one page to another one which their memory allocated together exceeds the limit. Let me explain more, for example, the first page memory size is 90 MB, which is less than 150 MB, and the second page is 70 MB. When navigating from the first page to the second, the Windows Phone OS builds the second page while it stays in the first one. That means that it already has 90 MB in the available 150 MB, and is trying to add another 70 MB for the second page, before releasing the resources related to the first one.
What is the Solution For That?
It's clear now that any page must have less than 150 or 300 MB, depending on the device RAM memory, but also the sum of any 2 pages being navigated from or to each other must not exceed the memory limit. In order to not make a lot of calculations, let's say that each page must not exceed 75 MB = 150 / 2.
How to Apply That in the Application?
I think it is very important to take care of the number of images and its resolution as follows:
- Don't put hundreds of images in one page! Remember you are building a mobile application which should be light and show only the most relevant items.
- There are some techniques which help to decrease the resolution of an image in order to decrease its memory size in the cache.
- Think about putting like 3 images or so in the first items of the list, and putting a repetitive image (as an icon) for the rest of the list.
Low and High-end Devices
In the above paragraph, I said we have to exceed 75 MB = 150 / 2. That's suitable especially for 512 MB devices. But why not take full advantage of the 1 GB RAM without exceeding 150 MB = 300 / 2.
In fact, it's possible to make 2 different pages: one contains resources that do not exceed 75 MB, and a second one doesn't exceeds 150 MB. Then choose which page to show depending on the device's RAM size.
Visual Studio 2013 makes it possible to do memory profiling for the Windows Phone application. You just enable that option, run and use the application. At the end, Visual Studio will generate a usage memory report.
You may find this is not the best option because this operation consumes a lot of CPU, don't give memory usage at real-time and find it a little bit difficult to find how much memory each page is consuming. Then you may want to try a very simple way to do memory profiling. You can get the amount of memory being used using the DeviceStatus.ApplicationCurrentMemoryUsage, and show its value in a
TextBlock for each page (of course, don't forget to remove it when publishing to the Store).
Not only images cause exceeding memory. But there's also layout controls. For example, one
PanoramaItem may use about 10 MB alone, so imagine you have 20
PanoramaItems ! The same thing for the
PivotItem control or the
HubTile (in the Phone Toolkit).
Try to remove some sections or controls from the page and note how much memory it was taking, so you make the best decision about which control to use.
Building a content reach application that doesn't crash on even in low end devices, that have less memory, requires knowledge about how much each resource or UI control is taking from the available limited memory.