From 91ecb36df50be3446809e9da2a8f571d157f7549 Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Wed, 10 Jul 2013 19:15:07 -0700 Subject: [PATCH] ActivityManagerService use lmkd low memory killer daemon -- DO NOT MERGE Change-Id: Ie2f8af1e411c28d7f03be56c356ec39e1d71558e --- core/java/android/os/Process.java | 13 -- core/jni/android_util_Process.cpp | 18 --- .../server/am/ActivityManagerService.java | 20 +-- .../com/android/server/am/ProcessList.java | 135 +++++++++++++----- 4 files changed, 113 insertions(+), 73 deletions(-) diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 631edd67957b8..057f516af17b5 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -891,19 +891,6 @@ public class Process { return true; } - /** - * Set the out-of-memory badness adjustment for a process. - * - * @param pid The process identifier to set. - * @param amt Adjustment value -- linux allows -16 to +15. - * - * @return Returns true if the underlying system supports this - * feature, else false. - * - * {@hide} - */ - public static final native boolean setOomAdj(int pid, int amt); - /** * Adjust the swappiness level for a process. * diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 601975af01b92..cbed99f9acad9 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -344,23 +344,6 @@ jint android_os_Process_getThreadPriority(JNIEnv* env, jobject clazz, return pri; } -jboolean android_os_Process_setOomAdj(JNIEnv* env, jobject clazz, - jint pid, jint adj) -{ -#ifdef HAVE_OOM_ADJ - char text[64]; - sprintf(text, "/proc/%d/oom_adj", pid); - int fd = open(text, O_WRONLY); - if (fd >= 0) { - sprintf(text, "%d", adj); - write(fd, text, strlen(text)); - close(fd); - } - return true; -#endif - return false; -} - jboolean android_os_Process_setSwappiness(JNIEnv *env, jobject clazz, jint pid, jboolean is_increased) { @@ -1023,7 +1006,6 @@ static const JNINativeMethod methods[] = { {"setThreadGroup", "(II)V", (void*)android_os_Process_setThreadGroup}, {"setProcessGroup", "(II)V", (void*)android_os_Process_setProcessGroup}, {"getProcessGroup", "(I)I", (void*)android_os_Process_getProcessGroup}, - {"setOomAdj", "(II)Z", (void*)android_os_Process_setOomAdj}, {"setSwappiness", "(IZ)Z", (void*)android_os_Process_setSwappiness}, {"setArgV0", "(Ljava/lang/String;)V", (void*)android_os_Process_setArgV0}, {"setUid", "(I)I", (void*)android_os_Process_setUid}, diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index fc66e45c0ceee..264a809ef0f0a 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 d3777c7ae1340..f5920c8db3555 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