Troubleshooting Memory Issues on Windows Mobile

Really many mobile developers have often various issues related to memory. This is obviously mainly related to the restrictions Windows CE has (till version 5.0) about memory-management, basically what Doug Boling called "Living within the box" here. Remember that Windows Mobile, even 6.1, still relies on Windows CE 5.0 components, therefore it still "suffers" the 32MB-limitation per process.

I've been involved in cases about memory so many times that I started blogging… Wink see my very first post "NETCF: Memory leak... now what??". And I’m glad to say that all the hints I’ve written in that post must have helped many developers, because since then I worked rarely on cases related to memory…

In any case, before saying that "the problem is with memory", you should consider having a solid understanding of how that works on Windows CE (till v5.0). There are many authoritative places where you can look at over the web and books; and many others that are specific to .NET Compact Framework. So I won’t repeat them here (unless you want so).

Apart from the bloat of info you can find in my old post, some other things you should know:

- In the past Motorola\Symbol did an excellent job on troubleshooting memory issues, and they developed a tool that is part of their Private SDK and that work on Motorola devices. So, if you’re specifically targeting Motorola\Symbol devices, if you think the problem is with memory then you must use it. Its name is "Remote Memory Viewer", but sincerely I don’t know if it’s still available. Consult with Motorola to check if this is the case.

- Remember that Remote Performance Monitor (RPM) offers not only the ability to compare the GC Heap at different times, but also to export data that can be seen on the PC’s Performance Monitor (Start\Run… "perfmon").

- In some very rare cases, especially on devices with additional hardware features (barcode, etc), a problem with the memory is something that can’t be resolved without modifying the architecture of the application: in some cases the application hits a limitation of the platform and a limit of your abilities as ISV Application Developers (compared to what an OEM can do with their platform, especially if "many" drivers have to be loaded by DEVICE.EXE). In general, for applications that may require so much memory, an architectural design is to split it into at least 2 applications: a shell that act as a guardian and kills background applications, and a main application doing the job.

- To emulate user’s interaction with UI and verify if disposing a form in a managed application actually marks the object as ready to be collected, an approach that you may use is to see what happens if, after showing and disposing a form "many" times and after "some" Garbage Collections, all the memory is really cleaned up. This way we'll know if the leak is due to something internal to that particular form for example. I'm simply talking about something similar to the following:

 int N = 1000;
for (int i = 1; i <= N; i++)
    if (i % 200 == 0) MessageBox.Show(i.ToString()); //simply to know it’s going
    //for example at this point you can click on RPM's "GC Heap"
    frmTest frm = new frmTest(/*...*/);
MessageBox.Show("Over. Done. Finito.");

After running the loop for N times, looking at RPM you should make sure that "some" Garbage Collections occurred and then you can look if in the GC Heap there are still frmTest objects alive.

- If the problem is with a v2.0 application, even SP2, make sure you're not hitting a bug, by verifying if running on the v3.5 addresses the issue (click here for details). However, this is a suggestion valid in general, and indeed I've already written as point 2 of a previous post.