How the Windows Mobile 5.0 Shell Handles Low Memory Situations
I've received a lot of questions over the last while as to how the Windows Mobile shell handles low memory on both Pocket PC and Smartphone and I thought it's about time somebody gave a decent explanation as to how the shell handles this situation. This is mostly an FYI post but hopefully if you're writing an app for Windows Mobile you'll also stop and consider how well your app will behave when confronted by a device running low on resources.
To start, low memory is a very important consideration to take into account when dealing with a resource constrained device such as a Pocket PC or Smartphone (or any other embedded device for that matter). Unlike the desktop we don't have a large source of memory to tap and no virtual memory (since we don’t require a device to have secondary storage that we could swap memory out to) so a device can quickly get into a state where most of the available memory is in use.
The Windows Mobile 5 shell runs a low memory check routine periodically (on Pocket PC this is done every 5 seconds, on Smartphone its 30 seconds) and assesses the state of the system memory. The routine will check to see if any action is required to keep a reasonable amount of memory free (the OEM ultimately decides what a reasonable amount is). Additionally, the kernel also monitors the amount of memory available and will nudge the shell whenever free memory drops below a certain threshold.
Below is a simplified diagram of the memory available for a device and the different memory thresholds that exist (note that the diagram is meant to show the relationship between thresholds and do not reflect relative values or sizes. Also, these threshold values can be modified by the OEM so there is no single value for them).
Hibernate
This is the amount of memory the shell tries to keep free at all times. If the amount of free memory falls below this value then the low memory check routine will try to free up memory. It will do this by first sending WM_HIBERNATE to all valid applications. When an application receives this message it should try to free as many resources as possible. When the low memory check routine runs again and the amount of free memory is still below the hibernate level then the shell will try to close the least recently used (LRU) application by sending a WM_CLOSE message. If the low memory check routine runs yet again and the amount of free memory is still below the hibernate level then the shell will call TerminateProcess on the LRU application that it last sent the WM_CLOSE message to.
Critical
If the low memory check routine is entered and the free memory is below this value the shell will send a WM_HIBERNATE message to all valid applications as above but it will then immediately try to close the LRU application without waiting to see if the WM_HIBERNATE messages were successful in bringing the amount of available memory above the critical level.
Execute
When launching an application the shell checks that there is at least this amount of memory free, otherwise it fails the application launch. This is done in order to prevent the application from taking up the last bit of available memory and potentially starving already running applications.
Kernel - Check
This is the value that the Windows CE kernel uses as its low memory threshold. When the available memory drops below this level, the kernel calls into the shell's out of memory handler (OOM) on a high priority thread. When the OOM handler receives this message it checks to see if the amount of free memory has dropped below the Kernel – Critical level. If the amount of free memory is greater than Kernel – Critical then the OOM handler simply calls the low memory check routine as described above. If there is less then Kernel – Critical amount of memory free then the following will happen:
Pocket PC – An "out of memory" dialog is displayed prompting the user to select an application to shut down.
Smartphone – The LRU application is closed without prompting the user.
What is a 'valid' Application ?
For an application to be considered by the low memory check routine as a candidate to receive a WM_HIBERNATE message or to be closed (if it’s the LRU application) it must meet the following criteria:
1. Have a top level window
2. Not have the WS_EX_TOOLWINDOW or WS_EX_NOACTIVATE style
3. Have been activated at some point
4. Not the foreground application (since this is the app the user is interacting with and they'd probably be pretty mad if it started to free resources as a result of receiving WM_HIBERNATE or was closed while they were using it)
What can my Application do?
The best thing your application can do when faced with a low memory situation is to play nicely with the rest of the device.
- If your application receives a WM_HIBERNATE message free up any resources not absolutely required.
- If you are planning on allocating a large amount of memory (or if a large allocation fails) you should call SHCloseApps, which will invoke the shell low memory check routine and will try to ensure that enough free memory exists. See below for an example:
#define MIN_MEMORY_TO_RUN 2*1024*1024
MEMORYSTATUS mst;
mst.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&mst);
If (mst.dwAvailPhys < MIN_MEMORY_TO_RUN)
{
// Try to free memory by asking Shell to shutdown apps
if (!SHCloseApps(MIN_MEMORY_TO_RUN))
{
// Handle the case where memory could not be freed
…
Comments
Anonymous
August 17, 2006
Great post, Pat. Can you also talk a little about how a developer can simulate any of these low memory states? Is there any way to make your app recieve WM_HIBERNATE when debugging, other than manually sending it from another app, or loading a lot of apps at once?Anonymous
August 17, 2006
Great post, I commend... Thank you. How can a C# app respond to these messages? Is there a clas available? I admit, I am new to C# development, and may have not noticed how, but, if you could, please post some hints, and that would be appreciated by many...!!! Thanks again.Anonymous
August 17, 2006
Great questions. In order to simulate a low memory state we internally use a simple app that gobbles up memory (we typically have to launch a couple instances of the app since a single app will usually exhaust virtual memory before it can exhaust the device memory, depending on the memory available on the device). I'll look into whether we can release that app externally and post back.
For C# developers (or managed developers in general) you can handle the MobileDevice.Hibernate event (see http://msdn2.microsoft.com/en-us/library/microsoft.windowsce.forms.mobiledevice.hibernate.aspx for details) to see whether you should start freeing up resources. Your event handler should try to free up as many resources as possible in order to avoid the situation where the shell has to close the LRU app (which could be your app if you're not in the foreground!).
-- Patrick DerksAnonymous
August 18, 2006
Hi WMTeam,
I know this is a bit of off the blog post topic - but I am struggling with getting a Unit Testing framework working with .Net Compact Framweork. I was wondering how you all use unit tests to help you design your software... Have you experimented with some light weight unit testing frameworks? and if yes - can you share the dll's?
PS: great job on the POOM the API is fantastic!Anonymous
August 21, 2006
this is a great post.. i was veri worried about how my application will handle low memory state. It is a pocket pc application. since reading your post, i try to copy a few large files (images) to the device and run my application. but it just hang there...
then i try to open other application and it prompt me that the program memory is low and to close other runnning application, as you have describe.
i looked in the link you have provide for managed developer (the application is a C#.net 1.0) but its for 2.0 only. so is there a way for .net compact 1.0 application to implement this? I need to maintain 1.0 for backward compatibility.
Thanks alot.Anonymous
August 22, 2006
Unfortunately I don't think there is a way to get the WM_HIBERNATE message from a .NET CF 1.0 app. The WM_HIBERNATE message is sent only to top level non-owned windows and unless I'm mistaken Microsoft.WindowsCE.Forms.MessageWindow doesn't meet this criteria.
--Patrick DerksAnonymous
August 22, 2006
Well my order is in and I am waiting in great anticipation for my SPV M3100 to arrive.&nbsp;I am looking...Anonymous
August 22, 2006
Hace poco le&iacute; un post en el blog de Windows Mobile acerca del manejo de situaciones de pocos recursosAnonymous
August 28, 2006
Hi,
In wm2003se (and probably in wm5) there is a registry entry called
HKLMSystemOOM
"AutoOOM"=dword:00000001
Does it change the Out-Of-Memory Policy? And in what way?
CheersAnonymous
August 28, 2006
The comment has been removedAnonymous
August 31, 2006
I'm just curious why Pocket PC keeps applications running in the background anyway when the user "closes" them. Why don't we have a "minimize" and a true "close" option? I'm not entirely sure how memory usage relates to energy consumption, but my pocket PC, when its battery gets low, tells me it doesn't have enough juice to run certain applications. Furthermore, the MSN Messenger says to stay signed out to avoid consuming the battery. It would therefore seem that the more you have in memory, the faster your battery will drain.
Personally, I'm quite a bit annoyed that the only way to actually close an application is to go into Windows Mobile's equivelant of the task manager to do it.Anonymous
September 01, 2006
I'm not a big fan of the "smart minimize" functionality either on PocketPC. I believe the original reasoning behind it was to save the user from having to worry about managing the list of running applications and to just let the shell do it for them.
You're right in that a running application could decrease battery life if its doing stuff, but most GUI applications just sit around waiting for the user to do something so they're not eating any CPU cycles. MSN Messenger is an exception since it has an active data connection to update your contacts, be ready for incoming messages etc.
--Pat DerksAnonymous
September 13, 2006
Does anybody know how to turn off that process that runs every 5/30 sec and tries to close applications or change the threshold for that process?
Thanks,
Alex
alex.49.98@mail.ruAnonymous
September 19, 2006
Patrick, in an earlier comment, you said:
"I'll look into whether we can release that app externally and post back."
What's the status of this, can you release the memory gobbling app externally?
Thanks,
JeffAnonymous
October 24, 2006
The comment has been removedAnonymous
November 02, 2006
Does anybody know any tool which can simulate low memory condition in Windows mobile 2005? Thanks, NarendraAnonymous
April 09, 2007
PingBack from http://www.ninelocks.com/blog/?p=15Anonymous
July 25, 2007
The comment has been removedAnonymous
August 30, 2007
If you have ever heard one of my talks on Windows Mobile development, you may remember me ranting a bitAnonymous
August 30, 2007
PingBack from http://msdnrss.thecoderblogs.com/2007/08/31/slaying-the-virtual-memory-monster/Anonymous
January 14, 2008
The comment has been removedAnonymous
January 29, 2008
Hi, I'm using a device with Windows CE 4.2 Our apps keep hangs suspected due to memory issues. Noticed the memory status in system properties shown available program memory < 1MB. Is this related to using Web Services in our apps !? Please advise.. Thanks in advance Herries EAnonymous
June 30, 2008
Nice article, i was trying to sense a low memory situation from a memory leak. For exhausting the memory just run couple of instances of the GPS sample provided with windows mobile 6 SDK, that sample got memory leak and will finally throw 'out of memory' exception.Anonymous
October 16, 2008
I have a question about the "valid" application. If Service.exe meet with 4 Criteria that you mentioned, Is Service.exe within the scope of "valid" application? If Service.exe has a Window, Does Shell Send WM_HIBERNATE, WM_CLOSE to the Window? How about Home.exe? Could you answer the question?Anonymous
April 08, 2009
hello i have developed application for windows 6.0 mobile o2 xda to communicate with Gps hardware .... i have used windows mobile 6 sdk and c# 3.5 for completing my application i have tested against fake gps provided by microsoft ... working fine.... I want to deploy it on O2 xda windows mobile.... Plz tell How this can be achieved....