Loading services/core/java/com/android/server/am/ActivityManagerService.java +40 −0 Original line number Original line Diff line number Diff line Loading @@ -9159,6 +9159,11 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println("-------------------------------------------------------------------------------"); pw.println("-------------------------------------------------------------------------------"); } } dumpBinderProxies(pw); dumpBinderProxies(pw); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } dumpLmkLocked(pw); } } } } Loading Loading @@ -9349,6 +9354,10 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { synchronized (this) { dumpOomLocked(fd, pw, args, opti, true); dumpOomLocked(fd, pw, args, opti, true); } } } else if ("lmk".equals(cmd)) { synchronized (this) { dumpLmkLocked(pw); } } else if ("permissions".equals(cmd) || "perm".equals(cmd)) { } else if ("permissions".equals(cmd) || "perm".equals(cmd)) { synchronized (this) { synchronized (this) { dumpPermissionsLocked(fd, pw, args, opti, true, null); dumpPermissionsLocked(fd, pw, args, opti, true, null); Loading Loading @@ -10383,6 +10392,37 @@ public class ActivityManagerService extends IActivityManager.Stub return true; return true; } } private boolean reportLmkKillAtOrBelow(PrintWriter pw, int oom_adj) { Integer cnt = ProcessList.getLmkdKillCount(0, oom_adj); if (cnt != null) { pw.println(" kills at or below oom_adj " + oom_adj + ": " + cnt); return true; } return false; } boolean dumpLmkLocked(PrintWriter pw) { pw.println("ACTIVITY MANAGER LMK KILLS (dumpsys activity lmk)"); Integer cnt = ProcessList.getLmkdKillCount(ProcessList.UNKNOWN_ADJ, ProcessList.UNKNOWN_ADJ); if (cnt == null) { return false; } pw.println(" Total number of kills: " + cnt); return reportLmkKillAtOrBelow(pw, ProcessList.CACHED_APP_MAX_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.CACHED_APP_MIN_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.SERVICE_B_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.PREVIOUS_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.HOME_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.SERVICE_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.HEAVY_WEIGHT_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.BACKUP_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.PERCEPTIBLE_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.VISIBLE_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.FOREGROUND_APP_ADJ); } /** /** * There are three ways to call this: * There are three ways to call this: * - no provider specified: dump all the providers * - no provider specified: dump all the providers Loading services/core/java/com/android/server/am/ProcessList.java +85 −29 Original line number Original line Diff line number Diff line Loading @@ -99,14 +99,22 @@ import dalvik.system.VMRuntime; import java.io.File; import java.io.File; import java.io.IOException; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStream; import java.io.InputStream; import java.io.PrintWriter; import java.io.PrintWriter; import java.nio.ByteBuffer; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.List; import java.util.List; import libcore.io.IoUtils; /** /** * Activity manager code dealing with processes. * Activity manager code dealing with processes. * * Method naming convention: * <ul> * <li> Methods suffixed with "LS" should be called within the {@link #sLmkdSocketLock} lock. * </ul> */ */ public final class ProcessList { public final class ProcessList { private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM; private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM; Loading Loading @@ -229,10 +237,12 @@ public final class ProcessList { // LMK_PROCPRIO <pid> <uid> <prio> // LMK_PROCPRIO <pid> <uid> <prio> // LMK_PROCREMOVE <pid> // LMK_PROCREMOVE <pid> // LMK_PROCPURGE // LMK_PROCPURGE // LMK_GETKILLCNT static final byte LMK_TARGET = 0; static final byte LMK_TARGET = 0; static final byte LMK_PROCPRIO = 1; static final byte LMK_PROCPRIO = 1; static final byte LMK_PROCREMOVE = 2; static final byte LMK_PROCREMOVE = 2; static final byte LMK_PROCPURGE = 3; static final byte LMK_PROCPURGE = 3; static final byte LMK_GETKILLCNT = 4; ActivityManagerService mService = null; ActivityManagerService mService = null; Loading Loading @@ -268,9 +278,17 @@ public final class ProcessList { private boolean mHaveDisplaySize; private boolean mHaveDisplaySize; private static Object sLmkdSocketLock = new Object(); @GuardedBy("sLmkdSocketLock") private static LocalSocket sLmkdSocket; private static LocalSocket sLmkdSocket; @GuardedBy("sLmkdSocketLock") private static OutputStream sLmkdOutputStream; private static OutputStream sLmkdOutputStream; @GuardedBy("sLmkdSocketLock") private static InputStream sLmkdInputStream; /** /** * Temporary to avoid allocations. Protected by main lock. * Temporary to avoid allocations. Protected by main lock. */ */ Loading Loading @@ -505,7 +523,7 @@ public final class ProcessList { buf.putInt(mOomAdj[i]); buf.putInt(mOomAdj[i]); } } writeLmkd(buf); writeLmkd(buf, null); SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve)); SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve)); } } // GB: 2048,3072,4096,6144,7168,8192 // GB: 2048,3072,4096,6144,7168,8192 Loading Loading @@ -978,7 +996,7 @@ public final class ProcessList { buf.putInt(pid); buf.putInt(pid); buf.putInt(uid); buf.putInt(uid); buf.putInt(amt); buf.putInt(amt); writeLmkd(buf); writeLmkd(buf, null); long now = SystemClock.elapsedRealtime(); long now = SystemClock.elapsedRealtime(); if ((now-start) > 250) { if ((now-start) > 250) { Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid Loading @@ -997,16 +1015,38 @@ public final class ProcessList { ByteBuffer buf = ByteBuffer.allocate(4 * 2); ByteBuffer buf = ByteBuffer.allocate(4 * 2); buf.putInt(LMK_PROCREMOVE); buf.putInt(LMK_PROCREMOVE); buf.putInt(pid); buf.putInt(pid); writeLmkd(buf); writeLmkd(buf, null); } } private static boolean openLmkdSocket() { /* * {@hide} */ public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) { ByteBuffer buf = ByteBuffer.allocate(4 * 3); ByteBuffer repl = ByteBuffer.allocate(4 * 2); buf.putInt(LMK_GETKILLCNT); buf.putInt(min_oom_adj); buf.putInt(max_oom_adj); if (writeLmkd(buf, repl)) { int i = repl.getInt(); if (i != LMK_GETKILLCNT) { Slog.e("ActivityManager", "Failed to get kill count, code mismatch"); return null; } return new Integer(repl.getInt()); } return null; } @GuardedBy("sLmkdSocketLock") private static boolean openLmkdSocketLS() { try { try { sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET); sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET); sLmkdSocket.connect( sLmkdSocket.connect( new LocalSocketAddress("lmkd", new LocalSocketAddress("lmkd", LocalSocketAddress.Namespace.RESERVED)); LocalSocketAddress.Namespace.RESERVED)); sLmkdOutputStream = sLmkdSocket.getOutputStream(); sLmkdOutputStream = sLmkdSocket.getOutputStream(); sLmkdInputStream = sLmkdSocket.getInputStream(); } catch (IOException ex) { } catch (IOException ex) { Slog.w(TAG, "lowmemorykiller daemon socket open failed"); Slog.w(TAG, "lowmemorykiller daemon socket open failed"); sLmkdSocket = null; sLmkdSocket = null; Loading @@ -1017,28 +1057,42 @@ public final class ProcessList { } } // Never call directly, use writeLmkd() instead // Never call directly, use writeLmkd() instead private static boolean writeLmkdCommand(ByteBuffer buf) { @GuardedBy("sLmkdSocketLock") private static boolean writeLmkdCommandLS(ByteBuffer buf) { try { try { sLmkdOutputStream.write(buf.array(), 0, buf.position()); sLmkdOutputStream.write(buf.array(), 0, buf.position()); } catch (IOException ex) { } catch (IOException ex) { Slog.w(TAG, "Error writing to lowmemorykiller socket"); Slog.w(TAG, "Error writing to lowmemorykiller socket"); IoUtils.closeQuietly(sLmkdSocket); sLmkdSocket = null; return false; } return true; } // Never call directly, use writeLmkd() instead @GuardedBy("sLmkdSocketLock") private static boolean readLmkdReplyLS(ByteBuffer buf) { int len; try { try { sLmkdSocket.close(); len = sLmkdInputStream.read(buf.array(), 0, buf.array().length); } catch (IOException ex2) { if (len == buf.array().length) { return true; } } catch (IOException ex) { Slog.w(TAG, "Error reading from lowmemorykiller socket"); } } IoUtils.closeQuietly(sLmkdSocket); sLmkdSocket = null; sLmkdSocket = null; return false; return false; } } return true; } private static void writeLmkd(ByteBuffer buf) { private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) { synchronized (sLmkdSocketLock) { for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) { if (sLmkdSocket == null) { if (sLmkdSocket == null) { if (openLmkdSocket() == false) { if (openLmkdSocketLS() == false) { try { try { Thread.sleep(1000); Thread.sleep(1000); } catch (InterruptedException ie) { } catch (InterruptedException ie) { Loading @@ -1049,15 +1103,17 @@ public final class ProcessList { // Purge any previously registered pids // Purge any previously registered pids ByteBuffer purge_buf = ByteBuffer.allocate(4); ByteBuffer purge_buf = ByteBuffer.allocate(4); purge_buf.putInt(LMK_PROCPURGE); purge_buf.putInt(LMK_PROCPURGE); if (writeLmkdCommand(purge_buf) == false) { if (writeLmkdCommandLS(purge_buf) == false) { // Write failed, skip the rest and retry // Write failed, skip the rest and retry continue; continue; } } } } if (writeLmkdCommand(buf)) { if (writeLmkdCommandLS(buf) && (repl == null || readLmkdReplyLS(repl))) { return; return true; } } } } } return false; } } static void killProcessGroup(int uid, int pid) { static void killProcessGroup(int uid, int pid) { Loading Loading
services/core/java/com/android/server/am/ActivityManagerService.java +40 −0 Original line number Original line Diff line number Diff line Loading @@ -9159,6 +9159,11 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println("-------------------------------------------------------------------------------"); pw.println("-------------------------------------------------------------------------------"); } } dumpBinderProxies(pw); dumpBinderProxies(pw); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } dumpLmkLocked(pw); } } } } Loading Loading @@ -9349,6 +9354,10 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { synchronized (this) { dumpOomLocked(fd, pw, args, opti, true); dumpOomLocked(fd, pw, args, opti, true); } } } else if ("lmk".equals(cmd)) { synchronized (this) { dumpLmkLocked(pw); } } else if ("permissions".equals(cmd) || "perm".equals(cmd)) { } else if ("permissions".equals(cmd) || "perm".equals(cmd)) { synchronized (this) { synchronized (this) { dumpPermissionsLocked(fd, pw, args, opti, true, null); dumpPermissionsLocked(fd, pw, args, opti, true, null); Loading Loading @@ -10383,6 +10392,37 @@ public class ActivityManagerService extends IActivityManager.Stub return true; return true; } } private boolean reportLmkKillAtOrBelow(PrintWriter pw, int oom_adj) { Integer cnt = ProcessList.getLmkdKillCount(0, oom_adj); if (cnt != null) { pw.println(" kills at or below oom_adj " + oom_adj + ": " + cnt); return true; } return false; } boolean dumpLmkLocked(PrintWriter pw) { pw.println("ACTIVITY MANAGER LMK KILLS (dumpsys activity lmk)"); Integer cnt = ProcessList.getLmkdKillCount(ProcessList.UNKNOWN_ADJ, ProcessList.UNKNOWN_ADJ); if (cnt == null) { return false; } pw.println(" Total number of kills: " + cnt); return reportLmkKillAtOrBelow(pw, ProcessList.CACHED_APP_MAX_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.CACHED_APP_MIN_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.SERVICE_B_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.PREVIOUS_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.HOME_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.SERVICE_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.HEAVY_WEIGHT_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.BACKUP_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.PERCEPTIBLE_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.VISIBLE_APP_ADJ) && reportLmkKillAtOrBelow(pw, ProcessList.FOREGROUND_APP_ADJ); } /** /** * There are three ways to call this: * There are three ways to call this: * - no provider specified: dump all the providers * - no provider specified: dump all the providers Loading
services/core/java/com/android/server/am/ProcessList.java +85 −29 Original line number Original line Diff line number Diff line Loading @@ -99,14 +99,22 @@ import dalvik.system.VMRuntime; import java.io.File; import java.io.File; import java.io.IOException; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStream; import java.io.InputStream; import java.io.PrintWriter; import java.io.PrintWriter; import java.nio.ByteBuffer; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.Arrays; import java.util.List; import java.util.List; import libcore.io.IoUtils; /** /** * Activity manager code dealing with processes. * Activity manager code dealing with processes. * * Method naming convention: * <ul> * <li> Methods suffixed with "LS" should be called within the {@link #sLmkdSocketLock} lock. * </ul> */ */ public final class ProcessList { public final class ProcessList { private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM; private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM; Loading Loading @@ -229,10 +237,12 @@ public final class ProcessList { // LMK_PROCPRIO <pid> <uid> <prio> // LMK_PROCPRIO <pid> <uid> <prio> // LMK_PROCREMOVE <pid> // LMK_PROCREMOVE <pid> // LMK_PROCPURGE // LMK_PROCPURGE // LMK_GETKILLCNT static final byte LMK_TARGET = 0; static final byte LMK_TARGET = 0; static final byte LMK_PROCPRIO = 1; static final byte LMK_PROCPRIO = 1; static final byte LMK_PROCREMOVE = 2; static final byte LMK_PROCREMOVE = 2; static final byte LMK_PROCPURGE = 3; static final byte LMK_PROCPURGE = 3; static final byte LMK_GETKILLCNT = 4; ActivityManagerService mService = null; ActivityManagerService mService = null; Loading Loading @@ -268,9 +278,17 @@ public final class ProcessList { private boolean mHaveDisplaySize; private boolean mHaveDisplaySize; private static Object sLmkdSocketLock = new Object(); @GuardedBy("sLmkdSocketLock") private static LocalSocket sLmkdSocket; private static LocalSocket sLmkdSocket; @GuardedBy("sLmkdSocketLock") private static OutputStream sLmkdOutputStream; private static OutputStream sLmkdOutputStream; @GuardedBy("sLmkdSocketLock") private static InputStream sLmkdInputStream; /** /** * Temporary to avoid allocations. Protected by main lock. * Temporary to avoid allocations. Protected by main lock. */ */ Loading Loading @@ -505,7 +523,7 @@ public final class ProcessList { buf.putInt(mOomAdj[i]); buf.putInt(mOomAdj[i]); } } writeLmkd(buf); writeLmkd(buf, null); SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve)); SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve)); } } // GB: 2048,3072,4096,6144,7168,8192 // GB: 2048,3072,4096,6144,7168,8192 Loading Loading @@ -978,7 +996,7 @@ public final class ProcessList { buf.putInt(pid); buf.putInt(pid); buf.putInt(uid); buf.putInt(uid); buf.putInt(amt); buf.putInt(amt); writeLmkd(buf); writeLmkd(buf, null); long now = SystemClock.elapsedRealtime(); long now = SystemClock.elapsedRealtime(); if ((now-start) > 250) { if ((now-start) > 250) { Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid Loading @@ -997,16 +1015,38 @@ public final class ProcessList { ByteBuffer buf = ByteBuffer.allocate(4 * 2); ByteBuffer buf = ByteBuffer.allocate(4 * 2); buf.putInt(LMK_PROCREMOVE); buf.putInt(LMK_PROCREMOVE); buf.putInt(pid); buf.putInt(pid); writeLmkd(buf); writeLmkd(buf, null); } } private static boolean openLmkdSocket() { /* * {@hide} */ public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) { ByteBuffer buf = ByteBuffer.allocate(4 * 3); ByteBuffer repl = ByteBuffer.allocate(4 * 2); buf.putInt(LMK_GETKILLCNT); buf.putInt(min_oom_adj); buf.putInt(max_oom_adj); if (writeLmkd(buf, repl)) { int i = repl.getInt(); if (i != LMK_GETKILLCNT) { Slog.e("ActivityManager", "Failed to get kill count, code mismatch"); return null; } return new Integer(repl.getInt()); } return null; } @GuardedBy("sLmkdSocketLock") private static boolean openLmkdSocketLS() { try { try { sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET); sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET); sLmkdSocket.connect( sLmkdSocket.connect( new LocalSocketAddress("lmkd", new LocalSocketAddress("lmkd", LocalSocketAddress.Namespace.RESERVED)); LocalSocketAddress.Namespace.RESERVED)); sLmkdOutputStream = sLmkdSocket.getOutputStream(); sLmkdOutputStream = sLmkdSocket.getOutputStream(); sLmkdInputStream = sLmkdSocket.getInputStream(); } catch (IOException ex) { } catch (IOException ex) { Slog.w(TAG, "lowmemorykiller daemon socket open failed"); Slog.w(TAG, "lowmemorykiller daemon socket open failed"); sLmkdSocket = null; sLmkdSocket = null; Loading @@ -1017,28 +1057,42 @@ public final class ProcessList { } } // Never call directly, use writeLmkd() instead // Never call directly, use writeLmkd() instead private static boolean writeLmkdCommand(ByteBuffer buf) { @GuardedBy("sLmkdSocketLock") private static boolean writeLmkdCommandLS(ByteBuffer buf) { try { try { sLmkdOutputStream.write(buf.array(), 0, buf.position()); sLmkdOutputStream.write(buf.array(), 0, buf.position()); } catch (IOException ex) { } catch (IOException ex) { Slog.w(TAG, "Error writing to lowmemorykiller socket"); Slog.w(TAG, "Error writing to lowmemorykiller socket"); IoUtils.closeQuietly(sLmkdSocket); sLmkdSocket = null; return false; } return true; } // Never call directly, use writeLmkd() instead @GuardedBy("sLmkdSocketLock") private static boolean readLmkdReplyLS(ByteBuffer buf) { int len; try { try { sLmkdSocket.close(); len = sLmkdInputStream.read(buf.array(), 0, buf.array().length); } catch (IOException ex2) { if (len == buf.array().length) { return true; } } catch (IOException ex) { Slog.w(TAG, "Error reading from lowmemorykiller socket"); } } IoUtils.closeQuietly(sLmkdSocket); sLmkdSocket = null; sLmkdSocket = null; return false; return false; } } return true; } private static void writeLmkd(ByteBuffer buf) { private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) { synchronized (sLmkdSocketLock) { for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) { if (sLmkdSocket == null) { if (sLmkdSocket == null) { if (openLmkdSocket() == false) { if (openLmkdSocketLS() == false) { try { try { Thread.sleep(1000); Thread.sleep(1000); } catch (InterruptedException ie) { } catch (InterruptedException ie) { Loading @@ -1049,15 +1103,17 @@ public final class ProcessList { // Purge any previously registered pids // Purge any previously registered pids ByteBuffer purge_buf = ByteBuffer.allocate(4); ByteBuffer purge_buf = ByteBuffer.allocate(4); purge_buf.putInt(LMK_PROCPURGE); purge_buf.putInt(LMK_PROCPURGE); if (writeLmkdCommand(purge_buf) == false) { if (writeLmkdCommandLS(purge_buf) == false) { // Write failed, skip the rest and retry // Write failed, skip the rest and retry continue; continue; } } } } if (writeLmkdCommand(buf)) { if (writeLmkdCommandLS(buf) && (repl == null || readLmkdReplyLS(repl))) { return; return true; } } } } } return false; } } static void killProcessGroup(int uid, int pid) { static void killProcessGroup(int uid, int pid) { Loading