How to configure Android's *internal* taskkiller

Search This thread

androcheck

Senior Member
Dec 7, 2009
235
413
john.zweng.at
Hi!

Note:
Sorry this posting got very long. But it will tell you how to configure Android's internal taskkiller which may help getting your hero really speedy again.. :) Without using any taskkiller.



Here the long story:
I just was curious if already someone tried to play around with Android's internal low-memory task killer.

We all know that Android uses a different way of handling processes. Instead of killing every process after its Activity ended, processes are kept until the system needs more memory. These processes usually should not harm the overall performance and should give speed improvements if you start an Activity again. That's the idea.

But when does Android kill a process? And which process? As far as I understood android keeps a LRU (last recently used) list and starts killing the oldest unneeded process. This way it is much smarter than any of the taskkillers we see in the Market.

Just for curiosity I started to investigate how this mechanism works. Please correct me if you think that I got something wrong:


What I found out:
ActivityManagerService.java tracks the "importance" of processes (is foreground, is running a service, ..) and reflects this importance by setting the "oom_adj" value of the process.

(For info: "oom_adj" is a value of every process under Linux which gives the kernel a hint, which process it can kill in an oom [out of memory] situation. You can see this value on every Linux 2.6 system in the proc directory: /proc/[PID]/oom_adj ). The higher this value is set, the more likely this process gets selected by the kernel's oom killer.)

It seems that on Android the current forefround application gets an oom_adj value of 0 and as soon it's not visible anymore it gets some higher value. I assume the concrete value is dependent by the processes' place in the LRU list.


The out-of-memory killer in the standard Linux kernel only runs in one situation: when the available memory is critical low. However in the Android Linux kernel there is implemented a more fine-grained handling of low memory situations.

I found the kernel source file "lowmemorykiller.c" (located in the kernel source tree under "drivers/misc/"; or look here for GIT source tree: http://tinyurl.com/lowmemkiller).


This module seems to be more configurable than the kernel's standard out-of-memory killer as you can define more than one memory limit, when it should get active and you can tell it which oom_adj values it may kill.

In other words:
You can say "if free memory goes below XXXX then kill some process with oom_adj greater then YYY; if free memory goes even more below than ZZZ then start to kill some processes with oom_adj greater than XYXY. and so on.."

So it's possible to define multiple memory criterias and matching processes which can be killed in these situations. Android seems to group running processes into 6 different categories (comments taken out of "ActivityManagerServer.java"):
Code:
FOREGROUND_APP:
    // This is the process running the current foreground app.  We'd really
    // rather not kill it! Value set in system/rootdir/init.rc on startup.

VISIBLE_APP:
    // This is a process only hosting activities that are visible to the
    // user, so we'd prefer they don't disappear. Value set in
    // system/rootdir/init.rc on startup.

SECONDARY_SERVER:
    // This is a process holding a secondary server -- killing it will not
    // have much of an impact as far as the user is concerned. Value set in
    // system/rootdir/init.rc on startup.

HIDDEN_APP:
    // This is a process only hosting activities that are not visible,
    // so it can be killed without any disruption. Value set in
    // system/rootdir/init.rc on startup.

CONTENT_PROVIDER:
    // This is a process with a content provider that does not have any clients
    // attached to it.  If it did have any clients, its adjustment would be the
    // one for the highest-priority of those processes.

EMPTY_APP:
    // This is a process without anything currently running in it.  Definitely
    // the first to go! Value set in system/rootdir/init.rc on startup.
    // This value is initalized in the constructor, careful when refering to
    // this static variable externally.
These 6 categories are reflected by 6 memory limits which are configured for the lowmemorykiller in the kernel.

Fortunately, it is possible to configure the lowmemorykiller at runtime! :)
(But only if you are root). The configuration is set in the file: "/sys/module/lowmemorykiller/parameters/minfree"

So if you want to see the current settings, you can do:

Code:
# cat /sys/module/lowmemorykiller/parameters/minfree
This should produce output like this (or similiar):
Code:
1536,2048,4096,5120,5632,6144

These values are the 6 memory limits on which Anedroid starts to kill processes of one of the 6 categories above. Be careful, the units of these values are pages!! 1 page = 4 kilobyte.

So the example above says that Anddroid starts killing EMPTY_APP processes if available memory goes below 24MB (=6144*4/1024). And it starts to kill unused CONTENT_PROVIDERs if available memory goes below 22MB (=5632*4/1024).


So if you want to try if your Hero goes faster when fewer processes are running you can try to adjust these settings. For example if you practically do not want any empty processes you can set the corresponding value very high. For example, you can set the values like this:

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

This example will tell Android to kill unused Content providers if less then 60MB is available and kill empty processes if available memory goes below 90MB.

All other processes will stay untouched! Do you see the advantage compared to process killers?


One word about durabilty:
If you change the settings like this, they are NOT PERMANENT. They will be gone after the next restart of your phone. So you can try to play around a little bit. Please share your results if you find some improvements! :)

To make this settings survive also reboots you need to somehow set this at startup. I am running Modaco's custom rom and added the command to the startup script /system/init.d/ramzswap.sh, but there may be other ways to do this.

Currently I also disabled compcache on my Hero and set the lowmemkiller very aggressive, as it seems to me that this makes my hero very responsive.

So these are my (current) settings:
Code:
echo "1536,3072,4096,21000,23000,25000" > /sys/module/lowmemorykiller/parameters/minfree
(and compcache disabled)

But play around.. I am glad about any feedback. :)
Please also give feedback if I am wrong or missed something!

Thx! :rolleyes:
 
Last edited:

felikz

Senior Member
Aug 23, 2009
345
6
i would be interested in changing the application which is startet when i long press on home (normally its the task changer of sense ui, but i want another program to be started)
 

awsy44

Senior Member
Jan 30, 2008
145
22
37
Auckland
this is excellent!, I just updated the ramzswap.sh to your settings and I can tell you it does an excellent job so far of running for like 20minutes, my ram is around 76 MB with facebook with all the htc widgets running, it usually drops to around 50 MB, does compcache save alot of ram when you disable it?

Thanks so much for the amazing info!, its hard someone to explain everything for you like you did.
 

inkredi

Senior Member
Dec 13, 2009
459
5
32
Miami
moustafakhalil.com
woah!! i cannot stand my phone when RAM is less than 100mb
i keep it around 115~130

anyway whats new in ur method? why not use the Kill-All widgets after setting the ignore list ..or smth like "Automatic Task Killer" ??
 

androcheck

Senior Member
Dec 7, 2009
235
413
john.zweng.at
The difference of this method compared to task killers like "Automatic Task Killer" is that there is no separate application involved.

There is no widget or taskkiller process which needs to be run.

Instead you configure the Android kernel itself how to handle processes. While taskkillers need to be run regularly (automatically or by hand) to check memory and kill processes, the way I described this gets done complete automatically by the Android kernel, immediately when available memory goes under the configured limits.

There is also no need for ignore-lists or something like this, as the Android kernel knows which applications it can kill and which not. Furthermore you can configure much more fine-grained when to kill which processes and the kernel is using the internal "last recently used" list and kills the least needed processes first.

External task killer only can kill processes "blindly", they cannot see which processes are "empty" (not hosting an Activity) or which have been in the background for the longest time, and so on..


When people tell you that taskkillers are evil, they mean that taskkillers interfere with Androids process management in a way this was never intended. The way I described you still let Android handling processes itself, but you just tell it to be more restrictive. :)

So this is far less invasive into the Android system and (should :)) have less side-effects..

But I'm still learning. I am a programmer who wants to understand things. And fortunately here we have the source to do so.. :cool:
 

androcheck

Senior Member
Dec 7, 2009
235
413
john.zweng.at
Thanks for the info! :)

Hmm.. but how can I change the init.rc? As it is placed directly in the root directory remounting and changing the file seems not to work (like on the the /system partiton).

I can remount and change the file, but the changes are gone after a reboot. The root dir is mounted as "rootfs".. No idea how to change files in there (without building a new ROM).
 
Last edited:

intronauta

Senior Member
Aug 29, 2009
281
106
Very interesting ;)

My minfree: 1536,2048,4096,5120,15360,23040 (compcache disabled)

The system is very fluid and responsive. I dont know if this is by the tweak or compcache, but I see in EStrong Task Manager just the necesary process, no more empty process and more space for hidden process, second. :)

Very curious.
 

Xfight

Member
Dec 16, 2009
10
0
Great Post !!

I try this for 12h

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

with compcache active and MCR 3.1 and hero has an incredible boost ! Apps load more quickly and fluidity is improved very well and i don't use anymore any "killall" app.

Background service also works perfectly.

Without this tweak, i noted random delay when many apps are loaded.

There is a way for disable compcache in MCR ?
 

androcheck

Senior Member
Dec 7, 2009
235
413
john.zweng.at
@Xfight: Glad to see, I could help you. :)
Regarding compcache: I disabled it (for testing) on MCR by commenting out the line
Code:
/system/xbin/insmod /system/lib/modules/ramzswap.ko disksize_kb=XXXXX
in "/system/init.d/ramzswap.sh"

Or just temporarily (until next restart):
Code:
# swapoff /dev/block/ramzswap0
 

khunjj

Senior Member
Sep 14, 2008
244
8
So exciting to hear this :) Anyway, I am some kind of new in linux programing. Would help a lot, if there is a step by step to add the command to the startup script /system/init.d/ramzswap.sh ;) Do I have to go to recovery mode to do so? And use which application or just normal text editor to edit the script?
Thnks,
 

Tzira

Senior Member
Sep 27, 2009
78
5
Campina
I get permission denied when I try to change the values
# echo "1536,2048,4096,5120,15360,23040" > /sys/module/lowmemorykiller/parameters/minfree
 

Foka002

Senior Member
May 12, 2008
343
126
This is just superb idea. I was looking for something like this for ages. Nice one mate.

By the way...

Tzira
I get permission denied when I try to change the values
# echo "1536,2048,4096,5120,15360,23040" > /sys/module/lowmemorykiller/parameters/minfree

Did you try type "su" and then the command ?
 
Last edited:

androcheck

Senior Member
Dec 7, 2009
235
413
john.zweng.at
UPDATE to make more clear what these 6 values mean, when you enter a command like this:

Code:
echo "1536,2048,4096,5120,15360,23040" > /sys/module/lowmemorykiller/parameters/minfree
      [B] #1   #2   #3   #4   #5    #6[/B]

Important: The unit of these numbers are "pages" (1 page = 4 kilobyte)

These define 6 limits of minimum "available" memory (which is not necessary equivalent to "free" memory under Linux, but this is an other story). These 6 limits are associated with 6 categories of processes under Android.

If the available memory goes below one of these limits, the kernel starts to kill processes of the corresponding category.

On Android the "ActivityManagerService" takes care of assigning processes into one of these categories (which means nothing more than setting an appropriate "oom_adj" value).

Details on the 6 categories:

#1: FOREGROUND_APP:
Only the current application in the foreground. This is the activity that is the focus for the user's actions.​

#2: VISIBLE_APP:
Applications which are not in the foreground but are still visble to the user. That is, another activity lies on top of it and that activity either is transparent or doesn't cover the full screen.​

#3: SECONDARY_SERVER:
First: The "HOME" application (or SenseUI on Hero) also falls into this category! So do not set this limit to high!
Further: All (secondary) services, which are currently running. These are all normal services as we know them from applications. ("Primary" services are life-critical services like the PhoneService which never will get killed by the lowmemorykiller.)

#4: HIDDEN_APP:
Any other Activity which falls not under #1 or #2. So any Activity as soon as it is not visible anymore (i.e. in the background, because of pressing Home, or starting another Activity).​

#5: CONTENT_PROVIDER:
Processes which host a content provider that does not have any clients connected to it.
For explanation: Content providers store and retrieve data and make it accessible to all applications. Examples are: the contacts content provider, the calendar content provider, the sms content provider, and so on. These allow different applications to access the same underlying data (contacts, calendar, ...).

#6: EMPTY_APP:
This is a process without anything currently running in it. On Android a prgrammer can call "finish()" to close an activity. The system still can decide to keep the "empty" process running, to avoid the startup overhead when the user needs the activity again. All processes in this group are empty processes.​


So, to sum up a little bit:


I definitely would be careful with the first 3 values, as they may affect directly the user experience! But it seems there is a wider range of settings we can try at the last 3 values. These applications could be safely killed. So try around until you find appropriate values for your needs. :)

As long as you just perform the "echo ..." command and do not change any startup script or something like this you should be on the safe side. If something goes wrong, just restart your phone and everything should be normal again.

Hope that helps.. ;)


[edit]
All said about this should apply to any Android device. Not only the Hero and not only Android 1.5. So try it also on Eclair! :)
[/edit]
 
Last edited:

Top Liked Posts

  • There are no posts matching your filters.
  • 86
    Hi!

    Note:
    Sorry this posting got very long. But it will tell you how to configure Android's internal taskkiller which may help getting your hero really speedy again.. :) Without using any taskkiller.



    Here the long story:
    I just was curious if already someone tried to play around with Android's internal low-memory task killer.

    We all know that Android uses a different way of handling processes. Instead of killing every process after its Activity ended, processes are kept until the system needs more memory. These processes usually should not harm the overall performance and should give speed improvements if you start an Activity again. That's the idea.

    But when does Android kill a process? And which process? As far as I understood android keeps a LRU (last recently used) list and starts killing the oldest unneeded process. This way it is much smarter than any of the taskkillers we see in the Market.

    Just for curiosity I started to investigate how this mechanism works. Please correct me if you think that I got something wrong:


    What I found out:
    ActivityManagerService.java tracks the "importance" of processes (is foreground, is running a service, ..) and reflects this importance by setting the "oom_adj" value of the process.

    (For info: "oom_adj" is a value of every process under Linux which gives the kernel a hint, which process it can kill in an oom [out of memory] situation. You can see this value on every Linux 2.6 system in the proc directory: /proc/[PID]/oom_adj ). The higher this value is set, the more likely this process gets selected by the kernel's oom killer.)

    It seems that on Android the current forefround application gets an oom_adj value of 0 and as soon it's not visible anymore it gets some higher value. I assume the concrete value is dependent by the processes' place in the LRU list.


    The out-of-memory killer in the standard Linux kernel only runs in one situation: when the available memory is critical low. However in the Android Linux kernel there is implemented a more fine-grained handling of low memory situations.

    I found the kernel source file "lowmemorykiller.c" (located in the kernel source tree under "drivers/misc/"; or look here for GIT source tree: http://tinyurl.com/lowmemkiller).


    This module seems to be more configurable than the kernel's standard out-of-memory killer as you can define more than one memory limit, when it should get active and you can tell it which oom_adj values it may kill.

    In other words:
    You can say "if free memory goes below XXXX then kill some process with oom_adj greater then YYY; if free memory goes even more below than ZZZ then start to kill some processes with oom_adj greater than XYXY. and so on.."

    So it's possible to define multiple memory criterias and matching processes which can be killed in these situations. Android seems to group running processes into 6 different categories (comments taken out of "ActivityManagerServer.java"):
    Code:
    FOREGROUND_APP:
        // This is the process running the current foreground app.  We'd really
        // rather not kill it! Value set in system/rootdir/init.rc on startup.
    
    VISIBLE_APP:
        // This is a process only hosting activities that are visible to the
        // user, so we'd prefer they don't disappear. Value set in
        // system/rootdir/init.rc on startup.
    
    SECONDARY_SERVER:
        // This is a process holding a secondary server -- killing it will not
        // have much of an impact as far as the user is concerned. Value set in
        // system/rootdir/init.rc on startup.
    
    HIDDEN_APP:
        // This is a process only hosting activities that are not visible,
        // so it can be killed without any disruption. Value set in
        // system/rootdir/init.rc on startup.
    
    CONTENT_PROVIDER:
        // This is a process with a content provider that does not have any clients
        // attached to it.  If it did have any clients, its adjustment would be the
        // one for the highest-priority of those processes.
    
    EMPTY_APP:
        // This is a process without anything currently running in it.  Definitely
        // the first to go! Value set in system/rootdir/init.rc on startup.
        // This value is initalized in the constructor, careful when refering to
        // this static variable externally.
    These 6 categories are reflected by 6 memory limits which are configured for the lowmemorykiller in the kernel.

    Fortunately, it is possible to configure the lowmemorykiller at runtime! :)
    (But only if you are root). The configuration is set in the file: "/sys/module/lowmemorykiller/parameters/minfree"

    So if you want to see the current settings, you can do:

    Code:
    # cat /sys/module/lowmemorykiller/parameters/minfree
    This should produce output like this (or similiar):
    Code:
    1536,2048,4096,5120,5632,6144

    These values are the 6 memory limits on which Anedroid starts to kill processes of one of the 6 categories above. Be careful, the units of these values are pages!! 1 page = 4 kilobyte.

    So the example above says that Anddroid starts killing EMPTY_APP processes if available memory goes below 24MB (=6144*4/1024). And it starts to kill unused CONTENT_PROVIDERs if available memory goes below 22MB (=5632*4/1024).


    So if you want to try if your Hero goes faster when fewer processes are running you can try to adjust these settings. For example if you practically do not want any empty processes you can set the corresponding value very high. For example, you can set the values like this:

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

    This example will tell Android to kill unused Content providers if less then 60MB is available and kill empty processes if available memory goes below 90MB.

    All other processes will stay untouched! Do you see the advantage compared to process killers?


    One word about durabilty:
    If you change the settings like this, they are NOT PERMANENT. They will be gone after the next restart of your phone. So you can try to play around a little bit. Please share your results if you find some improvements! :)

    To make this settings survive also reboots you need to somehow set this at startup. I am running Modaco's custom rom and added the command to the startup script /system/init.d/ramzswap.sh, but there may be other ways to do this.

    Currently I also disabled compcache on my Hero and set the lowmemkiller very aggressive, as it seems to me that this makes my hero very responsive.

    So these are my (current) settings:
    Code:
    echo "1536,3072,4096,21000,23000,25000" > /sys/module/lowmemorykiller/parameters/minfree
    (and compcache disabled)

    But play around.. I am glad about any feedback. :)
    Please also give feedback if I am wrong or missed something!

    Thx! :rolleyes:
    4

    This is a Hero thread and quite a few months old. Also FYI - taskillers are a fallacy. Increasing the amount of free ram will only serve to reduce the number of apps you can run simultaneously it will NOT speed up your phone.
    These settings could apply to all Android builds, as Android has a built-in task killer for memory management. And no, its not a fallacy (I mean the built-in Android task killer is not a fallacy). It does speed up the phone. The *free* RAM is not unused. Rather it's used by Linux to cache the file system, which does speed things up.

    You can see the real usage by doing:

    # cat /proc/meminfo
    MemTotal: 311340 kB
    MemFree: 3656 kB
    Buffers: 580 kB
    Cached: 92136 kB
    SwapCached: 0 kB
    Active: 194460 kB
    Inactive: 49624 kB
    Active(anon): 154344 kB
    Inactive(anon): 768 kB
    Active(file): 40116 kB
    Inactive(file): 48856 kB
    Unevictable: 2788 kB
    Mlocked: 0 kB
    SwapTotal: 0 kB
    SwapFree: 0 kB
    Dirty: 20 kB
    Writeback: 0 kB
    AnonPages: 154176 kB
    Mapped: 81012 kB
    Shmem: 956 kB
    Slab: 11380 kB
    SReclaimable: 2788 kB
    SUnreclaim: 8592 kB
    KernelStack: 3224 kB
    PageTables: 11800 kB
    NFS_Unstable: 0 kB
    Bounce: 0 kB
    WritebackTmp: 0 kB
    CommitLimit: 155668 kB
    Committed_AS: 6467652 kB
    VmallocTotal: 319488 kB
    VmallocUsed: 93716 kB
    VmallocChunk: 176132 kB

    In this case my Task Manager is reporting almost 100MB free but as you can see, 92MB of that is being used by the OS as cache, and the actual unused RAM is only about 4MB. Linux kernels use most of the "free" RAM for file system caching.
    2
    The difference of this method compared to task killers like "Automatic Task Killer" is that there is no separate application involved.

    There is no widget or taskkiller process which needs to be run.

    Instead you configure the Android kernel itself how to handle processes. While taskkillers need to be run regularly (automatically or by hand) to check memory and kill processes, the way I described this gets done complete automatically by the Android kernel, immediately when available memory goes under the configured limits.

    There is also no need for ignore-lists or something like this, as the Android kernel knows which applications it can kill and which not. Furthermore you can configure much more fine-grained when to kill which processes and the kernel is using the internal "last recently used" list and kills the least needed processes first.

    External task killer only can kill processes "blindly", they cannot see which processes are "empty" (not hosting an Activity) or which have been in the background for the longest time, and so on..


    When people tell you that taskkillers are evil, they mean that taskkillers interfere with Androids process management in a way this was never intended. The way I described you still let Android handling processes itself, but you just tell it to be more restrictive. :)

    So this is far less invasive into the Android system and (should :)) have less side-effects..

    But I'm still learning. I am a programmer who wants to understand things. And fortunately here we have the source to do so.. :cool:
    2
    These values can be directly edited in your initrc
    *APP_ADJ, *APP_MIN_ADJ, *ADJ, *PROVIDER_MEM, *SERVER_MEM and *APP_MEM
    2
    I'm not sure what the correlation is between the original list and the list in the ProcessList.java file. Are they just different names for the same thing? Did Google simply rename the categories with later versions of Android, but they are otherwise identical? I don't know. Some of the descriptions provided for them are word-for-word identical with the descriptions provided in the OP here (eg. for FOREGROUND_APP, VISIBLE_APP), but the descriptions of the others are quite different from each other.
    Since the OP was written, there have been a few additional categories added while a few have been renamed and a couple are basically gone.

    btw the OP was likely written during eclair days since the CM6 (froyo) source files that I have lack any mention of CONTENT_PROVIDER_ADJ.

    I haven't seen these changes discussed anywhere so what the heck...

    I have the ActivityManagerService.java from donut,eclair and froyo to compare with Jelly Bean's ProcessList.java so here is a comparison - going from least important types to most important...

    Gone. EMPTY_APP_ADJ - Has been replaced/melded with HIDDEN_APP_MAX_ADJ (see farther down)
    Code:
        // This is a process without anything currently running in it.  Definitely
        // the first to go! Value set in system/rootdir/init.rc on startup.
        // This value is initalized in the constructor, careful when refering to
        // this static variable externally.
        static final int EMPTY_APP_ADJ;

    Gone
    . CONTENT_PROVIDER_ADJ - I don't see it in froyo source... just donut and eclair
    Code:
        // This is a process with a content provider that does not have any clients
        // attached to it.  If it did have any clients, its adjustment would be the
        // one for the highest-priority of those processes.
        static int CONTENT_PROVIDER_ADJ;

    Same
    . HIDDEN_APP_MAX_ADJ/HIDDEN_APP_MIN_ADJ
    Code:
        // This is a process only hosting activities that are not visible,
        // so it can be killed without any disruption.
        static final int HIDDEN_APP_MAX_ADJ = 15;
        static int HIDDEN_APP_MIN_ADJ = 9;

    New
    . SERVICE_B_ADJ - This like the old SECONDARY_SERVER_ADJ but less important
    Code:
        // The B list of SERVICE_ADJ -- these are the old and decrepit
        // services that aren't as shiny and interesting as the ones in the A list.
        static final int SERVICE_B_ADJ = 8;

    New
    . PREVIOUS_APP_ADJ - Introduced with ICS. This is a good idea but they messed it up because they made it less important than the next category (btw I fix this via services.jar hacking/supercharging lol)
    Code:
        // This is the process of the previous application that the user was in.
        // This process is kept above other things, because it is very common to
        // switch back to the previous app.  This is important both for recent
        // task switch (toggling between the two top recent apps) as well as normal
        // UI flow such as clicking on a URI in the e-mail app to view in the browser,
        // and then pressing back to return to e-mail.
        static final int PREVIOUS_APP_ADJ = 7;

    Same
    . HOME_APP_ADJ
    Code:
        // This is a process holding the home application -- we want to try
        // avoiding killing it, even if it would normally be in the background,
        // because the user interacts with it so much.
        static final int HOME_APP_ADJ = 6;

    Renamed
    . SERVICE_ADJ used to be called SECONDARY_SERVER_ADJ. Is now an A list Service (vs the B list Service above)
    Code:
        // This is a process holding an application service -- killing it will not
        // have much of an impact as far as the user is concerned.
        static final int SERVICE_ADJ = 5;

    Same
    . BACKUP_APP_ADJ
    Code:
        // This is a process currently hosting a backup operation.  Killing it
        // is not entirely fatal but is generally a bad idea.
        static final int BACKUP_APP_ADJ = 4;

    New
    . HEAVY_WEIGHT_APP_ADJ - Introduced with Gingerbread
    Code:
        // This is a process with a heavy-weight application.  It is in the
        // background, but we want to try to avoid killing it.
        static final int HEAVY_WEIGHT_APP_ADJ = 3;

    New
    . PERCEPTIBLE_APP_ADJ - Introduced with Gingerbread. This are usually in the notification/status bar
    Code:
        // This is a process only hosting components that are perceptible to the
        // user, and we really want to avoid killing them, but they are not
        // immediately visible. An example is background music playback.
        static final int PERCEPTIBLE_APP_ADJ = 2;

    Same
    . VISIBLE_APP_ADJ
    Code:
        // This is a process only hosting activities that are visible to the
        // user, so we'd prefer they don't disappear.
        static final int VISIBLE_APP_ADJ = 1;

    Same
    . FOREGROUND_APP_ADJ
    Code:
        // This is the process running the current foreground app.  We'd really
        // rather not kill it!
        static final int FOREGROUND_APP_ADJ = 0;

    Renamed
    . PERSISTENT_PROC_ADJ used to be called CORE_SERVER_ADJ
    Code:
        // This is a system persistent process, such as telephony.  Definitely
        // don't want to kill it, but doing so is not completely fatal.
        static final int PERSISTENT_PROC_ADJ = -12;

    Same
    . SYSTEM_ADJ
    Code:
        // The system process runs at the default adjustment.
        static final int SYSTEM_ADJ = -16;
    Another thing that confuses me, is that the ProcessList.java states, on lines 114-115, that "the OOM killer only supports 6 slots, so we can't give it a different value for every possible kind of process." Then it lists the six specific categories which fill these slots (which I've listed above).
    The ADJ's of those 6 categories determine the upper limit of each slot and go in /sys/module/lowmemorykiller/parameters/adj

    They used to use the ADJs of those listed in the OP. I added in brackets what they were:
    FOREGROUND_APP_ADJ (0)
    VISIBLE_APP_ADJ (1)
    SECONDARY_SERVER_ADJ (2)
    HIDDEN_APP_ADJ (7)
    CONTENT_PROVIDER_ADJ (14)
    EMPTY_APP_ADJ (15)

    So the adj file used contain: 0,1,2,7,14,15

    Now in Jelly Bean, they use the ADJs of:
    FOREGROUND_APP_ADJ (0)
    VISIBLE_APP_ADJ (1)
    PERCEPTIBLE_APP_ADJ (2)
    BACKUP_APP_ADJ (4)
    HIDDEN_APP_MIN_ADJ (9)
    HIDDEN_APP_MAX_ADJ (15)

    If you notice, I had left the ADJs in the above snippets of code as ell.

    So the adj file in Jelly Bean typically contains: 0,1,2,4,9,15

    Remember that those 6 numbers are upper limits.
    HIDDEN_APP_MIN_ADJ with priority of 9, falls into slot 5.

    So...what if a category doesn't have one of those numbers?
    Well, SERVICE_B_ADJ, with a priority of 8, would fall into slot 5 since 8 falls between slot 4's upper limit (4) and slot 5's upper limit (9).
    HEAVY_WEIGHT_APP_ADJ is 3 so that would fall into slot 4.

    And that's how they arrange numerous ADJ values into 6 slots. :)

    btw Gingerbread's default adj file contained: 0,1,2,4,7,15.
    To make matters even more confusing for me, there's another list of process categories given at http://developer.android.com/reference/android/app/ActivityManager.RunningAppProcessInfo.html which uses entirely different names and descriptions again!

    Hope someone might enlighten me on this!
    Dont worry about that one too much but this code should be self explanatory:
    Code:
            int importance = app.memImportance;
            if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
                app.curAdj = adj;
                app.curSchedGroup = schedGroup;
                if (!interesting) {
                    // For this reporting, if there is not something explicitly
                    // interesting in this process then we will push it to the
                    // background importance.
                    importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
                } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
                    importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
                } else if (adj >= ProcessList.SERVICE_B_ADJ) {
                    importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
                } else if (adj >= ProcessList.HOME_APP_ADJ) {
                    importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
                } else if (adj >= ProcessList.SERVICE_ADJ) {
                    importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
                } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
                    importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
                } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
                    importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
                } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
                    importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
                } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
                    importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
                } else {
                    importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
                }
            }
Our Apps
Get our official app!
The best way to access XDA on your phone
Nav Gestures
Add swipe gestures to any Android
One Handed Mode
Eases uses one hand with your phone