Loading core/java/android/os/Process.java +0 −13 Original line number Diff line number Diff line Loading @@ -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. * Loading core/jni/android_util_Process.cpp +0 −18 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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}, Loading services/core/java/com/android/server/am/ActivityManagerService.java +11 −9 Original line number Diff line number Diff line Loading @@ -3592,9 +3592,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) { Loading Loading @@ -12319,6 +12323,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); Loading Loading @@ -15181,16 +15186,13 @@ public final class ActivityManagerService extends ActivityManagerNative } if (app.curAdj != app.setAdj) { if (Process.setOomAdj(app.pid, 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; } else { success = false; Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); } } if (app.setSchedGroup != app.curSchedGroup) { app.setSchedGroup = app.curSchedGroup; if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, services/core/java/com/android/server/am/ProcessList.java +102 −33 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 <minfree> <minkillprio> ... (up to 6 pairs) // LMK_PROCPRIO <pid> <prio> // LMK_PROCREMOVE <pid> 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. Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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; Loading @@ -217,20 +231,20 @@ final class ProcessList { } for (int i=0; i<mOomAdj.length; i++) { long low = mOomMinFreeLow[i]; long high = mOomMinFreeHigh[i]; mOomMinFree[i] = (long)(low + ((high-low)*scale)); int low = mOomMinFreeLow[i]; int high = mOomMinFreeHigh[i]; mOomMinFree[i] = (int)(low + ((high-low)*scale)); } if (minfree_abs >= 0) { for (int i=0; i<mOomAdj.length; i++) { mOomMinFree[i] = (long)((float)minfree_abs * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); } } if (minfree_adj != 0) { for (int i=0; i<mOomAdj.length; i++) { mOomMinFree[i] += (long)((float)minfree_adj * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); if (mOomMinFree[i] < 0) { mOomMinFree[i] = 0; } Loading @@ -242,15 +256,6 @@ final class ProcessList { // before killing background processes. mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024) / 3; for (int i=0; i<mOomAdj.length; i++) { if (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; Loading @@ -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<mOomAdj.length; i++) { buf.putInt((mOomMinFree[i]*1024)/PAGE_SIZE); buf.putInt(mOomAdj[i]); } writeLmkd(buf); SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve)); } // GB: 2048,3072,4096,6144,7168,8192 Loading Loading @@ -506,19 +516,78 @@ final class ProcessList { return mCachedRestoreLevel; } private void writeFile(String path, String data) { FileOutputStream fos = null; /** * Set the out-of-memory badness adjustment for a process. * * @param pid The process identifier to set. * @param amt Adjustment value -- lmkd allows -16 to +15. * * {@hide} */ public static final void setOomAdj(int pid, int amt) { if (amt == UNKNOWN_ADJ) return; ByteBuffer buf = ByteBuffer.allocate(4 * 3); buf.putInt(LMK_PROCPRIO); buf.putInt(pid); buf.putInt(amt); writeLmkd(buf); } /* * {@hide} */ public static final void remove(int pid) { ByteBuffer buf = ByteBuffer.allocate(4 * 2); buf.putInt(LMK_PROCREMOVE); buf.putInt(pid); writeLmkd(buf); } private static boolean openLmkdSocket() { try { fos = new FileOutputStream(path); fos.write(data.getBytes()); } catch (IOException e) { Slog.w(ActivityManagerService.TAG, "Unable to write " + path); } finally { if (fos != null) { sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET); sLmkdSocket.connect( new LocalSocketAddress("lmkd", LocalSocketAddress.Namespace.RESERVED)); sLmkdOutputStream = sLmkdSocket.getOutputStream(); } catch (IOException ex) { Slog.w(ActivityManagerService.TAG, "lowmemorykiller daemon socket open failed"); sLmkdSocket = null; return false; } return true; } private static void writeLmkd(ByteBuffer buf) { for (int i = 0; i < 3; i++) { if (sLmkdSocket == null) { if (openLmkdSocket() == false) { try { fos.close(); } catch (IOException e) { Thread.sleep(1000); } catch (InterruptedException ie) { } continue; } } try { sLmkdOutputStream.write(buf.array(), 0, buf.position()); return; } catch (IOException ex) { Slog.w(ActivityManagerService.TAG, "Error writing to lowmemorykiller socket"); try { sLmkdSocket.close(); } catch (IOException ex2) { } sLmkdSocket = null; } } } Loading Loading
core/java/android/os/Process.java +0 −13 Original line number Diff line number Diff line Loading @@ -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. * Loading
core/jni/android_util_Process.cpp +0 −18 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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}, Loading
services/core/java/com/android/server/am/ActivityManagerService.java +11 −9 Original line number Diff line number Diff line Loading @@ -3592,9 +3592,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) { Loading Loading @@ -12319,6 +12323,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); Loading Loading @@ -15181,16 +15186,13 @@ public final class ActivityManagerService extends ActivityManagerNative } if (app.curAdj != app.setAdj) { if (Process.setOomAdj(app.pid, 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; } else { success = false; Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); } } if (app.setSchedGroup != app.curSchedGroup) { app.setSchedGroup = app.curSchedGroup; if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
services/core/java/com/android/server/am/ProcessList.java +102 −33 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 <minfree> <minkillprio> ... (up to 6 pairs) // LMK_PROCPRIO <pid> <prio> // LMK_PROCREMOVE <pid> 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. Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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; Loading @@ -217,20 +231,20 @@ final class ProcessList { } for (int i=0; i<mOomAdj.length; i++) { long low = mOomMinFreeLow[i]; long high = mOomMinFreeHigh[i]; mOomMinFree[i] = (long)(low + ((high-low)*scale)); int low = mOomMinFreeLow[i]; int high = mOomMinFreeHigh[i]; mOomMinFree[i] = (int)(low + ((high-low)*scale)); } if (minfree_abs >= 0) { for (int i=0; i<mOomAdj.length; i++) { mOomMinFree[i] = (long)((float)minfree_abs * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); } } if (minfree_adj != 0) { for (int i=0; i<mOomAdj.length; i++) { mOomMinFree[i] += (long)((float)minfree_adj * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]); if (mOomMinFree[i] < 0) { mOomMinFree[i] = 0; } Loading @@ -242,15 +256,6 @@ final class ProcessList { // before killing background processes. mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024) / 3; for (int i=0; i<mOomAdj.length; i++) { if (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; Loading @@ -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<mOomAdj.length; i++) { buf.putInt((mOomMinFree[i]*1024)/PAGE_SIZE); buf.putInt(mOomAdj[i]); } writeLmkd(buf); SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve)); } // GB: 2048,3072,4096,6144,7168,8192 Loading Loading @@ -506,19 +516,78 @@ final class ProcessList { return mCachedRestoreLevel; } private void writeFile(String path, String data) { FileOutputStream fos = null; /** * Set the out-of-memory badness adjustment for a process. * * @param pid The process identifier to set. * @param amt Adjustment value -- lmkd allows -16 to +15. * * {@hide} */ public static final void setOomAdj(int pid, int amt) { if (amt == UNKNOWN_ADJ) return; ByteBuffer buf = ByteBuffer.allocate(4 * 3); buf.putInt(LMK_PROCPRIO); buf.putInt(pid); buf.putInt(amt); writeLmkd(buf); } /* * {@hide} */ public static final void remove(int pid) { ByteBuffer buf = ByteBuffer.allocate(4 * 2); buf.putInt(LMK_PROCREMOVE); buf.putInt(pid); writeLmkd(buf); } private static boolean openLmkdSocket() { try { fos = new FileOutputStream(path); fos.write(data.getBytes()); } catch (IOException e) { Slog.w(ActivityManagerService.TAG, "Unable to write " + path); } finally { if (fos != null) { sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET); sLmkdSocket.connect( new LocalSocketAddress("lmkd", LocalSocketAddress.Namespace.RESERVED)); sLmkdOutputStream = sLmkdSocket.getOutputStream(); } catch (IOException ex) { Slog.w(ActivityManagerService.TAG, "lowmemorykiller daemon socket open failed"); sLmkdSocket = null; return false; } return true; } private static void writeLmkd(ByteBuffer buf) { for (int i = 0; i < 3; i++) { if (sLmkdSocket == null) { if (openLmkdSocket() == false) { try { fos.close(); } catch (IOException e) { Thread.sleep(1000); } catch (InterruptedException ie) { } continue; } } try { sLmkdOutputStream.write(buf.array(), 0, buf.position()); return; } catch (IOException ex) { Slog.w(ActivityManagerService.TAG, "Error writing to lowmemorykiller socket"); try { sLmkdSocket.close(); } catch (IOException ex2) { } sLmkdSocket = null; } } } Loading