Phone evicting inactive applications from ram, despite plenty of memory free The phone (Jiayu G4S) is running Android 4.4.2, 2GB of ram, stock jiayu.es rom (kernel 3.4.67)

Stock configuration also sets up some swap in zram, I disabled it, does not seem to make a difference.

Task manager shows at any time at least 0.92GB free or more. It shows at most 12-13 cached inactive apps that are still in ram, a bit more if process limit is manually set to a high value (just for kicks I choose 100).

According to dumpsys meminfo, this is how it looks now:

Total RAM: 2016644 kB
 Free RAM: 883420 kB (230000 cached pss + 131652 cached + 521768 free)
 Used RAM: 852001 kB (805401 used pss + 1684 buffers + 8972 shmem + 35944 slab)
 Lost RAM: 281223 kB
     ZRAM: 4 kB physical used for 0 kB in swap (0 kB total swap)
   Tuning: 256 (large 512), oom 122880 kB, restore limit 40960 kB (high-end-gfx)


And yet, frequently used applications get periodically thrown out from memory (shown in task manager with 0.00b allocated), which results in a small delay at next launch.

oomkiller parameters seem sane

shell@G4:/ $ cat /sys/module/lowmemorykiller/parameters/minfree                
12288,15360,18432,21504,24576,30720


Why are frequently used programs kicked out, despite all that free memory? Is there anything I can configure (I have root access)?
And now to answer myself. Looking at Android 4.4.2 (KOT39H) sources, in ProcessList.java we have defined a maximum number of cached apps, set to an arbitrary value of 24:

static final int MAX_CACHED_APPS = 24;


This value is further split as follows by computeEmptyProcessLimit function: 2/3 goes to empty process limit and 1/3 goes to cached process limit.

So now we have an arbitrary limit of 16 for empty and 8 for cached processes. (But go buy a 3GB ram phone, to see how much unused memory you'll have)

In stock android, the only way to change this limit is at runtime, via setProcessLimit(), which requires rooted phone, an application manually installed in /system/priv-app and the SET_PROCESS_LIMIT permission granted.

(In CM11 for example it can also be set in build.prop, but this code is not present in stock 4.4.2)

Luckily there already is such an application on github, called SetAndroidProcessLimit, which, installed correctly, works (my thanks to the author)

Now I have 20 cached apps in ram, that's about all apps I frequently use, and any of them will start instantly, zero delay.



I also figured out how to modify MAX_CACHED_APPS directly in /system/framework/services.jar


download the jar to your pc, unpack the jar
decompile classes.dex with baksmali (or via apktool)
modify in ProcessList.smali and in ActivityManagerService.smali - because this is bytecode, you have to replace not only declaration of MAX_CACHED_APPS but every occurence of it with new desired value
recompile classes.dex
repack the jar
download to phone, replacing original jar (you have to remount rw /system)
reboot the phone; mine automatically will regenerate dalvik cache