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.




  1. If your application receives a WM_HIBERNATE message free up any resources not absolutely required. 


  2. 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 (25)

  1. MSDNArchive says:

    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?

  2. Channa says:

    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.

  3. windowsmobile says:

    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 Derks

  4. 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!

  5. cutie says:

    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.

  6. windowsmobile says:

    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 Derks

  7. Well my order is in and I am waiting in great anticipation for my SPV M3100 to arrive.&amp;nbsp;I am looking…

  8. Hace poco le&amp;iacute; un post en el blog de Windows Mobile acerca del manejo de situaciones de pocos recursos

  9. Tweakradje says:

    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?

    Cheers

  10. windowsmobile says:

    The AutoOOM reg key is undocumented and therefore its ill advised to use it. Basically at the moment it will prevent the PocketPC "Out of memory dialog" (described in the "Kernel – Critical" section above) from being displayed. The kernel will instead decide which app to kill on the users behalf.

    –Pat Derks

  11. Shaun Burks says:

    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.    

  12. windowsmobile says:

    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 Derks

  13. Alex says:

      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.ru

  14. Jeff says:

    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,

    Jeff

  15. Mike says:

    I assume that the low memory condition being checked here is physical memory only, since available virtual memory is a "per process" parameter.  My point is that app developers cannot rely on the shell to give them additional memory when they have expended their 32 MB of virtual memory, and since some Windows Mobile devices have consumed nearly half of the 32 MB process virtual memory in slot 0 with shared DLL’s, the likelihood of running out of virtual memory before physical memory is very high.

  16. Narendra says:

    Does anybody know any tool which can simulate low memory condition in Windows mobile 2005?

    Thanks,

    Narendra

  17. Dave Haupert says:

    This is a very helpful article, but I still have a few questions about this after reading it.

    We have an application that handles large chunks of data.  The process is that they are read into memory from a file and put into arrays.  These arrays are held in memory until the user closes the program or saves the file explicitly.  

    So now a low memory situation comes up and the WM_HIBERNATE comes along.  We can try to free things up, but the only way to do that is to write the data to memory, which uses even more memory at that point.  So we can only free a few things at this point not the big chunks.  

    Then the out of memory dialog comes up and asks user to choose an app. Say they choose our app.  Does it call us with the same event as the task manager close?  Do we have a way of knowing that we are closing because of an out of memory erorr?  Because if we did, we’d try to put the data on a storage card, or not attempt to write it out, knowing it would likely fail anyway and better to have the previous version than no version at all or a half written corrupted version.

    Further questions:

    Does this give us a set amount of time to close or does and then kill us (like the Shutdown calls on a regular windows desktop), or does it just kill us in this situation.  

    Thanks in advance!

  18. If you have ever heard one of my talks on Windows Mobile development, you may remember me ranting a bit

  19. Herries E says:

    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 E

  20. susmitha says:

    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.

  21. Jongsoon M says:

    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?

  22. vishav sood says:

    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….