Inside Android

Hey guys!  Jerry back with another neat trick you can do on your Android phone.  This one helps keep things running smoothly, and gives us some user control over Android's internal task killer.  Like most things that affect the low level operation of Android, this one requires root, but it's a good read even for you folks who don't feel the need to root (and break your warranty!) because you just might have a better understanding of what's going on behind the scenes.  Open up a couple extra tabs on your browser, get your phone (and maybe even your USB cable) ready and follow the break.

Oh, and a warning: This is pretty low-level stuff. It's not hard to do, but what it does is a bit advanced. Don't say we didn't warn you.

linux and android

You hear time and time again that Android runs on the Linux kernel.  The biggest benefit of this, is that Linux is stable, open source, and extremely hackable.  This means that many of those benefits carry over to Android as well.  Being able to tweak the low memory killer is one of those.  This is something that I have personal experience with, both the hard way and the easy way.  While this benefits every flavor of Android, phones running HTC Sense will show the most improvement. 

How the low memory killer works

When your phone boots up, a file inside the boot image (init.rc) sets the system parameters.  Things like the path to framework files, setting up your networks, and setting the limits at which programs are killed off to free RAM are done by this file.  Now a super-Android-geek might dig inside the init.rc file and completely customize the low memory killer, but you don't have to do this to still get good results.  The init.rc sets up six different "levels" of open applications.  Let's have a look at them:

  • FOREGROUND_APP: This is the application currently on the screen, and running
  • VISIBLE_APP: This is an application that is open, and running in the background because it's still doing something
  • SECONDARY_SERVER: This is a process (a service that an application needs) that is alive and ready in case it's needed to do something
  • HIDDEN_APP: This again is a process, that sits idle (but still alive) in case it's needed by an app that's alive and running

For the most part, we never want to adjust when these apps and processes are killed off.  They are the things that the programs we use need to properly function.  For the more bold and advanced users, changing settings for HIDDEN_APP settings is possible, albeit with a LOT of trial and error.  There's two more settings, and these are the ones most interesting to us today:

  • CONTENT_PROVIDER: This is apps that provide data (content) to the system.  HTC Facebook Sync? That's a CONTENT_PROVIDER.  So are things like the Android Market, or Fring.  If they are alive, they can refresh and provide the content they are supposed to at the set interval.  If you kill them, they can't of course.
  • EMPTY_APP: I call these "ghosts."  They are apps that you have opened, but are done with them.  Android uses a unique style of handling memory management.  When an activity is ended, instead of killing it off Android keeps the application in memory so that opening them again is a faster process.  Theses "ghost" apps use no battery or CPU time, they just fill RAM that would be otherwise empty. When this memory is needed by a different application or process, the RAM is flushed and made available for the new app. To satisfy the geekier people (like myself) Android does this by keeping a list of recently used apps, with the oldest apps in the list given the lowest priority -- they are killed first if RAM is needed elsewhere.  This is a perfect way to handle 'ghost' processes, so there's no need to touch this part ;)

The EMTY_APP level is where we can  play Robin Hood and gain some UI performance.  We rob from the rich (RAM used by apps we are done using) and give to the poor (our pool of free RAM).  This way WE decide when Android closes old, unused apps instead of letting the system decide for us. Things like this are why we root.

the linux top command

I want to stress -- there is nothing wrong with the way Android handles this out of the box.  It's efficient, works well every time, and keeps things stable.  It's our meddling and the need for instant gratification that is the real issue. Waiting .3 seconds longer never killed anyone.  But I'm just as guilty as anyone else, and want immediate results too, so let's do it!

How do we manipulate all this?

Remember earlier I said you didn't have to dig into cryptic start up files to change these settings?  Well you're gonna love this.  You can change things around with an app from the Market!  There are several that work, but I prefer MinFreeManager because it's lightweight and doesn't share any personal information like some of the others do. Lets have a look at how to set this bad boy up.

Step one -- delete any task manager you have running.  They are only going to interfere with what we're doing today.  If you don't, we're all going to point and laugh while our phones run smoothly :)

Step two -- download and install MinFreeManager

minfree manager QR code

[Market Link | AppBrain]


Step three -- open the app.  Press the back button to get rid of the keyboard (we'll talk about editing the numbers you see in a bit), and hit menu > presets.

MinFreeManager menu  minfree manager presets

Choose "Aggressive".  There's no sense in installing and running an app like this without running it at it's full potential.  If after a day or two you think you're seeing issues from running at these settings, you can try "mild" or tweak the numbers by hand.  Next hit "apply" to set the parameters.  If you'd like the settings to be applied at every reboot, menu >> apply at boot will take care of you.  For most everyone, that's it.  Enjoy having about 75-100 MB of free RAM all the time.

minfree aggressive settings  minfree manager success!
 

If you want to tweak the numbers yourself, each entry is the level of free RAM that apps and processes in each particular category will start to get killed.  Below are the default settings for Android.

minfree default

Notice nothing gets wiped from RAM until the amount of free RAM reaches 32 MB.  (If you've listened to me while I've stood on my soapbox, you know that in my opinion SenseUI just doesn't work well with less than ~40 MB of free RAM) At 32 MB or less free, the system will start killing the 'ghosts'.  We can work our way up the list and see that if we ever get down to 14 MB or less free, the system can (and will) kill the app you have running in the foreground.

If you decide to play with these numbers, be very careful with the top four numbers.  Monkeying with these can make things very unstable, and very ugly.  The Content Provider (read it again above) is less touchy, but setting it too high will make things like Facebook sync even more screwy that it already is.  The Empty App section is the free for all.  Having this set to anything less than 96 MB (IMO) defeats the purpose of using an app like this.  Tweak things, give it a couple hours to settle in and decide if it needs more tweaking. 

Protip: if 'Aggressive' settings are a bit too much, instead of trying 'mild' try changing the Content Provider number a bit smaller and see what happens.

LowMemKiller Geek Edition

Because Android runs on a Linux kernel, that means parameters are stored as plain text files.  these can be edited on the fly -- thats exactly what apps like MinFreeManager are doing.  If you'd rather not use a third party app to make these changes, you can easily change the values from the command line.  Fire up your favorite terminal client and follow along.

htc evo terminal

To check the current parameters for the MinFree setting:

su
cat /sys/module/lowmemorykiller/parameters/minfree

This will return a string of numbers, something like this:

1536,2048,4096,5120,5632,6144

These numbers are pages.  To Android, a page is equal to 4 kb.  So in the above example, the EMPTY_APP settings (last in the list -- 6144) is 24 MB.  6144 pages = 24576 kb = 24 MB.  The formula would be:

((6144 * 4)/ 1024) 

Therefore, a setting of 25000 would be equal to ~97MB (told you it was the Geek Edition!).

For a good starting point, and an example of how to change the numbers, try this:

su
echo "1536,2048,4096,5120,15360,23040" > /sys/module/lowmemorykiller/parameters/minfree

This sets things up so that whenever free RAM drops below 90MB, 'ghosts' are killed off in order, and if RAM ever drops below 60MB, CONTENT_PROVIDERS get killed off.  Everything else is left unmolested by the kernel. 

Think about that for a second -- no more worrying about keeping things like clock and gmail alive and on the task killers whitelist, because we specify what kinds of apps and processes can be killed off to free up memory.

Once you have a set of numbers that work well for you, it's easy to streamline the process of applying it when you reboot.  Yes, these changes go away at each reboot as they are stored in a virtual disk (the Ramdisk) that erases when the phone is turned off.  You'll need a text editor that can save files in a format readable by Unix.  Nothing made by Microsoft is going to work.  I always recommend Notepad ++ to Windows users with a need to edit Unix files.  Grab it, and install it.

Open a blank file and paste the following in it:

echo "1536,2048,4096,5120,15360,23040" > /sys/module/lowmemorykiller/parameters/minfree

of course change the default settings to your desired settings.  Save the file as freeram with no extension. 

save as a unix text file with NO EXTENSION

Hook up your phone to your computer and push the freeram file to /system/bin.  Then at the command line prompt:

su
cd /system/bin
chmod 744 freeram
exit
exit

Now reboot your phone, and once it's loaded open your terminal and type in:

su
freeram
exit

To set YOUR parameters instead of the default Android parameters.  You'll need to do this at every reboot, or edit it into the init.rc file, which is waayyy too geeky to cover here.  We have a forum for that. :)

Whether you like the easy way, or prefer the more hardcore way, give it a try.  It's easy to revert, and its 100 percent free.

Till next time,
Jerry

 
There are 23 comments

Kedar says:

And I thought rooting looked hard...

meyerweb says:

Heck, using MinFreeManager this is a piece of cake.

BTW, this works with unRevoked, so you don't have to do a full root to use this.

Qazme says:

You have to have full root to use UnRevoked last time I checked. UnRevoked just flashes a recovery mod, you still have to root the phone.

tallbruva says:

Or you could just use Auto Memory Manager by Mad Squirrel and get the exact same functionality without the extra steps/hassle.

gbhil#AC says:

1. Exactly what extra steps are involved?
2. I prefer to not send data to third parties whenever possible.

sjcea says:

Doesnt work ?? when I try to apply or apply at reboot all it says is it failed , no matter what I do this is what I get , Droid Inc.

dkoss says:

Do you have root and did you give the app permission?

ezun says:

This is awesome! I spent that last 8 months learning linux for MythTV and when I get my D-Inc this is going to come in handy!

Thank you for putting this together - very easy to follow and the detail about what is actually happening helps tremendously.

dkoss says:

As always, another helpful tutorial from Jerry to keep our phones running at optimal speeds. Seems to be working as expected.Thanks.

laffen13 says:

Is there any advantages using MinFreeManager over AutoKiller? I have been using AutoKiller with the agressive settings and have had great luck!

gbhil#AC says:

AutoKiller sends usage data. Noting really wrong with that, but I prefer to be told before I comply :) Other than that, no differences. All the apps that adjust this setting are simply doing what I showed how to do by hand -- it's the only way to do it.

Cyan Lite says:

The problem with this is that it allows app developers to have an entire ecosystem where they never have to free resources or shut down their system; allowing only for the OS to go garbage collection. Then you have situations on some devices where you get a phone call, and it takes an extra 5 seconds for you to be able to answer it because the OS is trying to free memory to display the caller ID picture and ringtone. In the meantime, you hear the phone ring once (if at all) but to the other caller it has rang 6 or 7 times.

As an app developer, why can't we just have an "Application.exit()" function to ensure our application has fully closed and is removed from memory? There's nothing worse than getting bad feedback from a user who downloaded our app and complain because "it stays in the background and eats battery after exiting".

I'd also like some control over what gets shut down. On Some HTC devices (Eris in particular) the "Sense" UI application will get task-killed by the OS if you are doing heavy multi-tasking, especially watching YouTube or Flash videos.

storm14k says:

I'm 50/50 on that. Its the same as Java itself when you think about it. Get rid of all the references and let the GC worry about the memory. I think maybe a reason they have not given devs this ability is because of the way Android apps were meant to work. They are all supposed to be able to use each other (though not many are really taking full advantage of this). Devs aren't going to know the usage patterns for the intents they have exposed. So they could code to always close their apps and an activity in their app becomes a very commonly called piece of functionality by other apps but because its always closed its slow to startup. Then users would unfairly look at all the calling apps as being slow. Its probably just best that the OS handles this. What they should do maybe is write really extensive guidelines for efficient Java development. Make sure devs know how to minimize the memory footprint of their app especially when it goes to the background.

As for the users complaining about "apps in the background eating battery" thats all about misinformation. I don't know exactly how it started but Jobs has certainly helped to keep it spreading. I really don't understand how people continue to say this when you can see exactly whats been draining the battery and 9/10 times theres none of your installed apps anywhere near the top of the list. But they just keep repeating "running in background....draining battery". Maybe Google can come up with another way to combat this ignorance in Gingerbread.

kapaa1980 says:

Thanks Jerry great tutorial!

kmatheny says:

Awesome! Had to go from Aggressive to Mild though. Having a launcher, streaming music, weather, and my stopwatch running seemed to freeze and reboot my phone (this is a common combination in my working out, so I can't have my phone freeze every time I go to workout.) Even going to Mild made a noticeable improvement on my phones performance. Great tip!

Ponic says:

Anyone know if the app is Evo compatible? It doesn't seem to save settings on boot. Rooted and given SU permissions, still nada.

srkmagnus says:

Very good read and how-to. Thanks, Jerry.

imex99 says:

i'm running this app with aggresive,,,, anyway to monitor or see whats its doing?

JTEastwood says:

This is the reason i needed to go for root. Oh my! This is what i was waiting for. i always thought the memory was going too low before the os would start killing apps. This is beautiful.... and the tethering that came with root got me a little excited i must admit!!!!

onevision83 says:

I'm not getting push email from my gmail when I run on aggressive. Any counsel on this?

mtbhk44 says:

This is a total disaster. Took my battery life from 15 hours to 5 hours. Rooted, Kangerade 1.1. My phone was running consistently at 45 Deg Celsius. Crazy. Uninstalled!

bdmridgback says:

My battery was the same deal, I was upwards of 14-18 hours and the last two days since the install, I was lucky to get 5-7 hours out of it.
Sucks, don't install and make these changes.
Uninstalled too!

Melon Bread says:

Good Stuff, Thank You.
I as Pretty Much Done With TasKillers