The last few weeks I’ve been talking about Linux memory management. There was one final topic I wanted to talk about and that’s how Android uses the out-of-memory mechanism built into the kernel to manage memory.
Android is getting some play in embedded systems, but you have to remember it is primarily meant to run phones and similar devices where the user is the focal point of the system. The user’s experience is the main focus of how Android manages memory.
If you recall, the kernel has the OOM killer that selects processes to kill when memory is low. Android uses a similar mechanism, but it doesn’t just wait until there is no memory. Instead, it defines several different memory levels.
It is easier to explain this with a straightforward example. Suppose Android defined three different levels (it defines more, but for now let’s say three for simplicity). The first level is whatever program you are using right now on your Android device. The second level is things that you are actively using in the background; for example, a running music player or software to check for e-mail are active but not visible. The third level is for programs you have been using but you’ve switched away from. The operating system assumes you might switch back at any moment.
The operating system will associate a free memory target with each level (and you can adjust it, if you like). So if memory drops below, say, 100K, Android might start killing the level 3 programs until there is more than 100K free. If free memory drops below 25K, it might start killing the level 2 programs. The limit for killing the foreground application would be very small, since that would be rude to the end user.
The real Android system actually uses six levels:
FOREGROUND_APP – The application you are currently using
VISIBLE_APP – An application that is visible but not in the foreground
SECONDAY_SERVER – A process providing services
HIDDEN_APP – A process that is hidden, but may be needed by a running program
CONTENT_PROVIDER – Apps that provide data to the system (for example, synchronizing with the Market)
EMPTY_APP – An application you were using, but is not currently active
You can control the memory limits by writing to /sys/module/lowmemorykiller/parameters/minfree and /sys/module/lowmemorykiller/parameters/adj. The memory size is in 4K pages, not bytes, so be careful. By understanding these limits and setting the oom_adj parameter for given processes in /proc, you can exercise great control over how the system manages memory.
Naturally, in a hard real-time system, you don’t want all this thrashing around with memory. But then again, you really aren’t going to use Android for an actual hard real-time system, are you?
If you are on a system with Google Market access (for example, your phone) you can download a few programs that can control the memory scheme. Search for AMM, for example, in the market. There is also a script called V6 Supercharger. It isn’t as user-friendly, but since it is a script, it is easy to look inside and see what it is doing. These tools can actually help a sluggish phone or tablet, which is what most people are using them for.
So that’s all about memory for a little while. Are you using Android in any projects? And are you using it fairly “stock” or do you meddle with it to suit your nefarious purposes? Leave a comment and share your thoughts.