Tuning android for low ram devices

Post on 09-May-2015

1.616 views 0 download

Transcript of Tuning android for low ram devices

Memory TuningAndroid for Low-RAM

DevicesChris Kühl & Iago López Galeiras, Endocode AG

What's low-RAM?< 512MB

512MB? That's so 2012!Why do that to yourself?

You have no choice ;)Mod-maintainer for older deviceAndroid on embedded devicesVirtualized Android, anyone?

What to tune?AppsDalvik VMActivity ManagerLinux kernel

AppsBe a good citizen

Apps that manage their own memory well make the wholesystem run better

Keep Your Apps TrimGoogle says,

You should implement onTrimMemory(int) toincrementally release memory based on current

system constraints.

7 Trim LevelsRunning Cached

TRIM_MEMORY_RUNNING_MODERATE TRIM_MEMORY_BACKGROUND

TRIM_MEMORY_RUNNING_LOW TRIM_MEMORY_MODERATE

TRIM_MEMORY_RUNNING_CRITICAL TRIM_MEMORY_COMPLETE

...and TRIM_MEMORY_UI_HIDDEN

TRIM_MEMORY_COMPLETE ≈ onLowMemory

Dalvik VMAndroid Java VMDEX formatZygote

Dalvik is chattyDalvik's logcat output can paint a pretty good picture.

12-30 15:35:43.135: D/dalvikvm(15368): GC_EXPLICIT freed 39K, 66% free 2349K/6788K, paused 24ms+8ms, total 129ms12-30 15:35:43.682: D/dalvikvm(15368): GC_CONCURRENT freed 282K, 5% free 10382K/10823K, paused 5ms+4ms12-30 15:35:44.043: D/dalvikvm(15368): GC_CONCURRENT freed 319K, 5% free 10507K/10951K, paused 3ms+3ms12-30 15:35:44.723: D/dalvikvm(15368): GC_CONCURRENT freed 364K, 5% free 10568K/11079K, paused 3ms+4ms12-30 15:35:44.803: D/dalvikvm(15368): GC_FOR_ALLOC freed 312K, 6% free 10549K/11207K, paused 31ms12-30 15:35:45.034: D/dalvikvm(15368): GC_FOR_ALLOC freed 316K, 6% free 10542K/11207K, paused 48ms12-30 15:35:45.074: D/dalvikvm(15368): GC_FOR_ALLOC freed 1K, 6% free 10631K/11207K, paused 43ms

Dalvik PropertiesGenerally set these in PRODUCT_PROPERTY_OVERRIDES.

PRODUCT_PROPERTY_OVERRIDES := \ dalvik.vm.heapstartsize=5m \ dalvik.vm.heapgrowthlimit=64m \ dalvik.vm.heapsize=128m \ dalvik.vm.heaptargetutilization=0.80 \ dalvik.vm.heapminfree=512k \ dalvik.vm.heapmaxfree=2m

Dalvik VM - JITGoogle says...

For the really low-memory devices, we recommendthe JIT be disabled entirely.

Can save up to 1.5MB per process!

ActivityManagerManaging activities since 2008

ActivityManager & Memorymanagement

Continually ranks apps based on their importance to the user.

Adjustmentsstatic final int HIDDEN_APP_MAX_ADJ = 15;static int HIDDEN_APP_MIN_ADJ = 9;static final int SERVICE_B_ADJ = 8;static final int PREVIOUS_APP_ADJ = 7;static final int HOME_APP_ADJ = 6;static final int SERVICE_ADJ = 5;static final int BACKUP_APP_ADJ = 4;static final int HEAVY_WEIGHT_APP_ADJ = 3;static final int PERCEPTIBLE_APP_ADJ = 2;static final int VISIBLE_APP_ADJ = 1;static final int FOREGROUND_APP_ADJ = 0;static final int PERSISTENT_PROC_ADJ = -12;static final int SYSTEM_ADJ = -16;

lowmemorykillerA kernel module to preempt the oom and provide an interface

for user-space to prioritize apps

cat /sys/module/lowmemorykiller/parameters/adj0,1,2,4,9,15cat /sys/module/lowmemorykiller/parameters/minfree3031,4218,5406,7454,8642,10158

Configuringlowmemorykiller

private final int[] mOomAdj = new int[] { FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ, BACKUP_APP_ADJ, HIDDEN_APP_MIN_ADJ, HIDDEN_APP_MAX_ADJ };

private final long[] mOomMinFreeLow = new long[] { 8192, 12288, 16384, 24576, 28672, 32768 };

private final long[] mOomMinFreeHigh = new long[] { 32768, 40960, 49152, 57344, 65536, 81920 };

dumpsys meminfo

Total PSS by OOM adjustment: 18642 kB: System 18642 kB: system (pid 451) 13979 kB: Persistent 9884 kB: com.android.systemui (pid 1791) 4095 kB: com.android.phone (pid 689) 18349 kB: Foreground 18349 kB: com.android.launcher (pid 3106) 18895 kB: Visible 9498 kB: com.google.process.gapps (pid 735) 7078 kB: com.google.process.location (pid 667) 2319 kB: com.android.smspush (pid 795) 8222 kB: Perceptible 5623 kB: com.android.inputmethod.latin (pid 646) 2599 kB: com.android.location.fused (pid 676) 2810 kB: A Services 2810 kB: de.telekom.droidsync (pid 3117) 45844 kB: Background 14552 kB: android.process.acore (pid 3133) 5566 kB: com.google.android.syncadapters.calendar (pid 3270) 5475 kB: com.google.android.apps.genie.geniewidget (pid 3185) 4940 kB: com.google.android.gsf.login (pid 3254) 4362 kB: com.android.browser (pid 3359) 3898 kB: com.android.calendar (pid 3305) 3691 kB: com.android.providers.calendar (pid 3286) 3360 kB: com.cyanogenmod.lockclock (pid 3327)

dumpsys activity oom (1/3)

OOM levels: SYSTEM_ADJ: -16 PERSISTENT_PROC_ADJ: -12 FOREGROUND_APP_ADJ: 0 VISIBLE_APP_ADJ: 1 PERCEPTIBLE_APP_ADJ: 2 HEAVY_WEIGHT_APP_ADJ: 3 BACKUP_APP_ADJ: 4 SERVICE_ADJ: 5 HOME_APP_ADJ: 6 PREVIOUS_APP_ADJ: 7 SERVICE_B_ADJ: 8 HIDDEN_APP_MIN_ADJ: 10 HIDDEN_APP_MAX_ADJ: 15

dumpsys activity oom (2/3)

Process OOM control: PERS # 7: adj=sys /F trm=15 451:system/1000 (fixed) oom: max=-16 hidden=10 client=10 empty=10 curRaw=-16 setRaw=-16 cur=-16 set=-16 keeping=true hidden=false empty=false hasAboveClient=false PERS #10: adj=pers /F trm=15 689:com.android.phone/1001 (fixed) oom: max=-12 hidden=10 client=10 empty=10 curRaw=-12 setRaw=-12 cur=-12 set=-12 keeping=true hidden=false empty=false hasAboveClient=false PERS # 3: adj=pers /F trm=15 1791:com.android.systemui/u0a10030 (fixed) oom: max=-12 hidden=10 client=10 empty=10 curRaw=-12 setRaw=-12 cur=-12 set=-12 keeping=true hidden=false empty=false hasAboveClient=false Proc # 0: adj=fore /FA trm=15 3106:com.android.launcher/u0a10022 (top-activity) oom: max=15 hidden=10 client=10 empty=10 curRaw=0 setRaw=0 cur=0 set=0 keeping=true hidden=false empty=false hasAboveClient=false Proc # 9: adj=vis /F trm=15 795:com.android.smspush/u0a10032 (service) com.android.smspush/.WapPushManager<=Proc{689:com.android.phone/1001} oom: max=15 hidden=10 client=10 empty=10 curRaw=1 setRaw=1 cur=1 set=1 keeping=true hidden=false empty=true hasAboveClient=false

dumpsys activity oom (3/3)

Processes that are waiting to GC: Process ProcessRecord{422a4260 735:com.google.process.gapps/u0a10033} lowMem=true, last gced=3110616 ms ago, last lowMem=18198 ms ago Process ProcessRecord{422f13b0 451:system/1000} lowMem=true, last gced=3110616 ms ago, last lowMem=18198 ms ago Process ProcessRecord{4247c388 667:com.google.process.location/u0a10033} lowMem=true, last gced=3110616 ms ago, last lowMem=18198 ms ago Process ProcessRecord{4231a630 646:com.android.inputmethod.latin/u0a10021} lowMem=true, last gced=3110616 ms ago, last lowMem=18198 ms ago Process ProcessRecord{4250cfe0 676:com.android.location.fused/u0a10018} lowMem=true, last gced=3110616 ms ago, last lowMem=18198 ms ago Process ProcessRecord{422f2dd8 1791:com.android.systemui/u0a10030} lowMem=true, last gced=3110616 ms ago, last lowMem=18198 ms ago

Now for the

Kernel Bits

KSMKernel SamePage Merging

KSM can save about 20-30MB of RAM if given a chance

Enabling KSMThis is easy-peasy

echo 1 | tee /sys/kernel/mm/ksm/runecho 1000 | tee /sys/kernel/mm/ksm/sleep_millisecsecho 128 | tee /sys/kernel/mm/ksm/pages_to_scan

Oh yeah...You need to mark pages as mergeable.

void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) {

...

if (result != MAP_FAILED && (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) != 0) { ErrnoRestorer errno_restorer; madvise(result, size, MADV_MERGEABLE); }

return result;}

Is it working?dumpsys meminfo answers this

Total PSS: 126741 kB KSM: 6672 kB saved from shared 1128 kB 24552 kB unshared; 102936 kB volatile

extra_free_kbytesRaises the low water mark used to trigger kswapd

THE END