From 91ecb36df50be3446809e9da2a8f571d157f7549 Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Wed, 10 Jul 2013 19:15:07 -0700 Subject: ActivityManagerService use lmkd low memory killer daemon -- DO NOT MERGE Change-Id: Ie2f8af1e411c28d7f03be56c356ec39e1d71558e --- .../android/server/am/ActivityManagerService.java | 20 +-- .../java/com/android/server/am/ProcessList.java | 135 ++++++++++++++++----- 2 files changed, 113 insertions(+), 42 deletions(-) (limited to 'services') diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index fc66e45..264a809 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -3603,9 +3603,13 @@ public final class ActivityManagerService extends ActivityManagerNative */ private final void handleAppDiedLocked(ProcessRecord app, boolean restarting, boolean allowRestart) { + int pid = app.pid; cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); if (!restarting) { removeLruProcessLocked(app); + if (pid > 0) { + ProcessList.remove(pid); + } } if (mProfileProc == app) { @@ -12388,6 +12392,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean restarting, boolean allowRestart, int index) { if (index >= 0) { removeLruProcessLocked(app); + ProcessList.remove(app.pid); } mProcessesToGc.remove(app); @@ -15250,16 +15255,13 @@ public final class ActivityManagerService extends ActivityManagerNative } if (app.curAdj != app.setAdj) { - if (Process.setOomAdj(app.pid, app.curAdj)) { - if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( - TAG, "Set " + app.pid + " " + app.processName + - " adj " + app.curAdj + ": " + app.adjType); - app.setAdj = app.curAdj; - } else { - success = false; - Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); - } + ProcessList.setOomAdj(app.pid, app.curAdj); + if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( + TAG, "Set " + app.pid + " " + app.processName + + " adj " + app.curAdj + ": " + app.adjType); + app.setAdj = app.curAdj; } + if (app.setSchedGroup != app.curSchedGroup) { app.setSchedGroup = app.curSchedGroup; if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, diff --git a/services/java/com/android/server/am/ProcessList.java b/services/java/com/android/server/am/ProcessList.java index d3777c7..f5920c8 100644 --- a/services/java/com/android/server/am/ProcessList.java +++ b/services/java/com/android/server/am/ProcessList.java @@ -18,6 +18,8 @@ package com.android.server.am; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; import android.app.ActivityManager; import com.android.internal.util.MemInfoReader; @@ -26,6 +28,8 @@ import com.android.server.wm.WindowManagerService; import android.content.res.Resources; import android.graphics.Point; import android.os.SystemProperties; +import android.net.LocalSocketAddress; +import android.net.LocalSocket; import android.util.Slog; import android.view.Display; @@ -141,6 +145,16 @@ final class ProcessList { // Threshold of number of cached+empty where we consider memory critical. static final int TRIM_LOW_THRESHOLD = 5; + // Low Memory Killer Daemon command codes. + // These must be kept in sync with the definitions in lmkd.c + // + // LMK_TARGET ... (up to 6 pairs) + // LMK_PROCPRIO + // LMK_PROCREMOVE + static final byte LMK_TARGET = 0; + static final byte LMK_PROCPRIO = 1; + static final byte LMK_PROCREMOVE = 2; + // These are the various interesting memory levels that we will give to // the OOM killer. Note that the OOM killer only supports 6 slots, so we // can't give it a different value for every possible kind of process. @@ -150,18 +164,18 @@ final class ProcessList { }; // These are the low-end OOM level limits. This is appropriate for an // HVGA or smaller phone with less than 512MB. Values are in KB. - private final long[] mOomMinFreeLow = new long[] { + private final int[] mOomMinFreeLow = new int[] { 8192, 12288, 16384, 24576, 28672, 32768 }; // These are the high-end OOM level limits. This is appropriate for a // 1280x800 or larger screen with around 1GB RAM. Values are in KB. - private final long[] mOomMinFreeHigh = new long[] { + private final int[] mOomMinFreeHigh = new int[] { 49152, 61440, 73728, 86016, 98304, 122880 }; // The actual OOM killer memory levels we are using. - private final long[] mOomMinFree = new long[mOomAdj.length]; + private final int[] mOomMinFree = new int[mOomAdj.length]; private final long mTotalMemMb; @@ -169,6 +183,9 @@ final class ProcessList { private boolean mHaveDisplaySize; + private static LocalSocket sLmkdSocket; + private static OutputStream sLmkdOutputStream; + ProcessList() { MemInfoReader minfo = new MemInfoReader(); minfo.readMemInfo(); @@ -202,9 +219,6 @@ final class ProcessList { + " dh=" + displayHeight); } - StringBuilder adjString = new StringBuilder(); - StringBuilder memString = new StringBuilder(); - float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp; if (scale < 0) scale = 0; else if (scale > 1) scale = 1; @@ -217,20 +231,20 @@ final class ProcessList { } for (int i=0; i= 0) { for (int i=0; i 0) { - adjString.append(','); - memString.append(','); - } - adjString.append(mOomAdj[i]); - memString.append((mOomMinFree[i]*1024)/PAGE_SIZE); - } - // Ask the kernel to try to keep enough memory free to allocate 3 full // screen 32bpp buffers without entering direct reclaim. int reserve = displayWidth * displayHeight * 4 * 3 / 1024; @@ -268,10 +273,15 @@ final class ProcessList { } } - //Slog.i("XXXXXXX", "******************************* MINFREE: " + memString); if (write) { - writeFile("/sys/module/lowmemorykiller/parameters/adj", adjString.toString()); - writeFile("/sys/module/lowmemorykiller/parameters/minfree", memString.toString()); + ByteBuffer buf = ByteBuffer.allocate(4 * (2*mOomAdj.length + 1)); + buf.putInt(LMK_TARGET); + for (int i=0; i