summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2014-10-31 22:44:23 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-10-31 22:44:24 +0000
commitf34fa3e7aa9be9bf24c955a9ebf34022e4b88c25 (patch)
treeba984c30ae6e607d34a907a3ddf4b01743b77c26
parent30e5113000877e053ba4f30b5962a42a4d11fa6e (diff)
parent6edb5c665dcb024ae7cfb95b9a92e30dcc5777c1 (diff)
downloadframeworks_base-f34fa3e7aa9be9bf24c955a9ebf34022e4b88c25.zip
frameworks_base-f34fa3e7aa9be9bf24c955a9ebf34022e4b88c25.tar.gz
frameworks_base-f34fa3e7aa9be9bf24c955a9ebf34022e4b88c25.tar.bz2
Merge "Improve low on RAM reporting." into lmp-mr1-dev
-rw-r--r--core/java/com/android/internal/util/MemInfoReader.java4
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java520
2 files changed, 305 insertions, 219 deletions
diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java
index 1dd9464..b71fa06 100644
--- a/core/java/com/android/internal/util/MemInfoReader.java
+++ b/core/java/com/android/internal/util/MemInfoReader.java
@@ -106,4 +106,8 @@ public final class MemInfoReader {
public long getZramTotalSizeKb() {
return mInfos[Debug.MEMINFO_ZRAM_TOTAL];
}
+
+ public long[] getRawInfo() {
+ return mInfos;
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9f1ce0b..9179cc4 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1606,197 +1606,7 @@ public final class ActivityManagerService extends ActivityManagerNative
final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
Thread thread = new Thread() {
@Override public void run() {
- final SparseArray<ProcessMemInfo> infoMap
- = new SparseArray<ProcessMemInfo>(memInfos.size());
- for (int i=0, N=memInfos.size(); i<N; i++) {
- ProcessMemInfo mi = memInfos.get(i);
- infoMap.put(mi.pid, mi);
- }
- updateCpuStatsNow();
- synchronized (mProcessCpuTracker) {
- final int N = mProcessCpuTracker.countStats();
- for (int i=0; i<N; i++) {
- ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
- if (st.vsize > 0) {
- long pss = Debug.getPss(st.pid, null);
- if (pss > 0) {
- if (infoMap.indexOfKey(st.pid) < 0) {
- ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
- ProcessList.NATIVE_ADJ, -1, "native", null);
- mi.pss = pss;
- memInfos.add(mi);
- }
- }
- }
- }
- }
-
- long totalPss = 0;
- for (int i=0, N=memInfos.size(); i<N; i++) {
- ProcessMemInfo mi = memInfos.get(i);
- if (mi.pss == 0) {
- mi.pss = Debug.getPss(mi.pid, null);
- }
- totalPss += mi.pss;
- }
- Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
- @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
- if (lhs.oomAdj != rhs.oomAdj) {
- return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
- }
- if (lhs.pss != rhs.pss) {
- return lhs.pss < rhs.pss ? 1 : -1;
- }
- return 0;
- }
- });
-
- StringBuilder tag = new StringBuilder(128);
- StringBuilder stack = new StringBuilder(128);
- tag.append("Low on memory -- ");
- appendMemBucket(tag, totalPss, "total", false);
- appendMemBucket(stack, totalPss, "total", true);
-
- StringBuilder logBuilder = new StringBuilder(1024);
- logBuilder.append("Low on memory:\n");
-
- boolean firstLine = true;
- int lastOomAdj = Integer.MIN_VALUE;
- for (int i=0, N=memInfos.size(); i<N; i++) {
- ProcessMemInfo mi = memInfos.get(i);
-
- if (mi.oomAdj != ProcessList.NATIVE_ADJ
- && (mi.oomAdj < ProcessList.SERVICE_ADJ
- || mi.oomAdj == ProcessList.HOME_APP_ADJ
- || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
- if (lastOomAdj != mi.oomAdj) {
- lastOomAdj = mi.oomAdj;
- if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
- tag.append(" / ");
- }
- if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
- if (firstLine) {
- stack.append(":");
- firstLine = false;
- }
- stack.append("\n\t at ");
- } else {
- stack.append("$");
- }
- } else {
- tag.append(" ");
- stack.append("$");
- }
- if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
- appendMemBucket(tag, mi.pss, mi.name, false);
- }
- appendMemBucket(stack, mi.pss, mi.name, true);
- if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
- && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
- stack.append("(");
- for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
- if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
- stack.append(DUMP_MEM_OOM_LABEL[k]);
- stack.append(":");
- stack.append(DUMP_MEM_OOM_ADJ[k]);
- }
- }
- stack.append(")");
- }
- }
-
- logBuilder.append(" ");
- logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
- logBuilder.append(' ');
- logBuilder.append(ProcessList.makeProcStateString(mi.procState));
- logBuilder.append(' ');
- ProcessList.appendRamKb(logBuilder, mi.pss);
- logBuilder.append(" kB: ");
- logBuilder.append(mi.name);
- logBuilder.append(" (");
- logBuilder.append(mi.pid);
- logBuilder.append(") ");
- logBuilder.append(mi.adjType);
- logBuilder.append('\n');
- if (mi.adjReason != null) {
- logBuilder.append(" ");
- logBuilder.append(mi.adjReason);
- logBuilder.append('\n');
- }
- }
-
- logBuilder.append(" ");
- ProcessList.appendRamKb(logBuilder, totalPss);
- logBuilder.append(" kB: TOTAL\n");
-
- long[] infos = new long[Debug.MEMINFO_COUNT];
- Debug.getMemInfo(infos);
- logBuilder.append(" MemInfo: ");
- logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
- logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
- logBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
- logBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
- logBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
- logBuilder.append(" ");
- logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
- logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
- logBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
- logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
- if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
- logBuilder.append(" ZRAM: ");
- logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
- logBuilder.append(" kB RAM, ");
- logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
- logBuilder.append(" kB swap total, ");
- logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
- logBuilder.append(" kB swap free\n");
- }
- Slog.i(TAG, logBuilder.toString());
-
- StringBuilder dropBuilder = new StringBuilder(1024);
- /*
- StringWriter oomSw = new StringWriter();
- PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
- StringWriter catSw = new StringWriter();
- PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
- String[] emptyArgs = new String[] { };
- dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
- oomPw.flush();
- String oomString = oomSw.toString();
- */
- dropBuilder.append(stack);
- dropBuilder.append('\n');
- dropBuilder.append('\n');
- dropBuilder.append(logBuilder);
- dropBuilder.append('\n');
- /*
- dropBuilder.append(oomString);
- dropBuilder.append('\n');
- */
- StringWriter catSw = new StringWriter();
- synchronized (ActivityManagerService.this) {
- PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
- String[] emptyArgs = new String[] { };
- catPw.println();
- dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
- catPw.println();
- mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
- false, false, null);
- catPw.println();
- dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
- catPw.flush();
- }
- dropBuilder.append(catSw.toString());
- addErrorToDropBox("lowmem", null, "system_server", null,
- null, tag.toString(), dropBuilder.toString(), null, null);
- //Slog.i(TAG, "Sent to dropbox:");
- //Slog.i(TAG, dropBuilder.toString());
- synchronized (ActivityManagerService.this) {
- long now = SystemClock.uptimeMillis();
- if (mLastMemUsageReportTime < now) {
- mLastMemUsageReportTime = now;
- }
- }
+ reportMemUsage(memInfos);
}
};
thread.start();
@@ -13927,6 +13737,35 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ private static final int KSM_SHARED = 0;
+ private static final int KSM_SHARING = 1;
+ private static final int KSM_UNSHARED = 2;
+ private static final int KSM_VOLATILE = 3;
+
+ private final long[] getKsmInfo() {
+ long[] longOut = new long[4];
+ final int[] SINGLE_LONG_FORMAT = new int[] {
+ Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
+ };
+ long[] longTmp = new long[1];
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
+ SINGLE_LONG_FORMAT, null, longTmp, null);
+ longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
+ longTmp[0] = 0;
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
+ SINGLE_LONG_FORMAT, null, longTmp, null);
+ longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
+ longTmp[0] = 0;
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
+ SINGLE_LONG_FORMAT, null, longTmp, null);
+ longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
+ longTmp[0] = 0;
+ Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
+ SINGLE_LONG_FORMAT, null, longTmp, null);
+ longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
+ return longOut;
+ }
+
final void dumpApplicationMemoryUsage(FileDescriptor fd,
PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
boolean dumpDetails = false;
@@ -14272,7 +14111,7 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
+ memInfo.getFreeSizeKb()); pw.print(" kB (");
pw.print(cachedPss); pw.print(" cached pss + ");
- pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
+ pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
} else {
pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
@@ -14306,32 +14145,16 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println(memInfo.getSwapFreeSizeKb());
}
}
- final int[] SINGLE_LONG_FORMAT = new int[] {
- Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
- };
- long[] longOut = new long[1];
- Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
- SINGLE_LONG_FORMAT, null, longOut, null);
- long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
- longOut[0] = 0;
- Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
- SINGLE_LONG_FORMAT, null, longOut, null);
- long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
- longOut[0] = 0;
- Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
- SINGLE_LONG_FORMAT, null, longOut, null);
- long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
- longOut[0] = 0;
- Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
- SINGLE_LONG_FORMAT, null, longOut, null);
- long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+ final long[] ksm = getKsmInfo();
if (!isCompact) {
- if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
- pw.print(" KSM: "); pw.print(sharing);
+ if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
+ || ksm[KSM_VOLATILE] != 0) {
+ pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]);
pw.print(" kB saved from shared ");
- pw.print(shared); pw.println(" kB");
- pw.print(" "); pw.print(unshared); pw.print(" kB unshared; ");
- pw.print(voltile); pw.println(" kB volatile");
+ pw.print(ksm[KSM_SHARED]); pw.println(" kB");
+ pw.print(" "); pw.print(ksm[KSM_UNSHARED]);
+ pw.print(" kB unshared; ");
+ pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
}
pw.print(" Tuning: ");
pw.print(ActivityManager.staticGetMemoryClass());
@@ -14351,9 +14174,9 @@ public final class ActivityManagerService extends ActivityManagerNative
}
pw.println();
} else {
- pw.print("ksm,"); pw.print(sharing); pw.print(",");
- pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
- pw.println(voltile);
+ pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
+ pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
+ pw.print(","); pw.println(ksm[KSM_VOLATILE]);
pw.print("tuning,");
pw.print(ActivityManager.staticGetMemoryClass());
pw.print(',');
@@ -14372,6 +14195,265 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
+ String name) {
+ sb.append(" ");
+ sb.append(ProcessList.makeOomAdjString(oomAdj));
+ sb.append(' ');
+ sb.append(ProcessList.makeProcStateString(procState));
+ sb.append(' ');
+ ProcessList.appendRamKb(sb, pss);
+ sb.append(" kB: ");
+ sb.append(name);
+ }
+
+ private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
+ appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
+ sb.append(" (");
+ sb.append(mi.pid);
+ sb.append(") ");
+ sb.append(mi.adjType);
+ sb.append('\n');
+ if (mi.adjReason != null) {
+ sb.append(" ");
+ sb.append(mi.adjReason);
+ sb.append('\n');
+ }
+ }
+
+ void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
+ final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
+ for (int i=0, N=memInfos.size(); i<N; i++) {
+ ProcessMemInfo mi = memInfos.get(i);
+ infoMap.put(mi.pid, mi);
+ }
+ updateCpuStatsNow();
+ synchronized (mProcessCpuTracker) {
+ final int N = mProcessCpuTracker.countStats();
+ for (int i=0; i<N; i++) {
+ ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
+ if (st.vsize > 0) {
+ long pss = Debug.getPss(st.pid, null);
+ if (pss > 0) {
+ if (infoMap.indexOfKey(st.pid) < 0) {
+ ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
+ ProcessList.NATIVE_ADJ, -1, "native", null);
+ mi.pss = pss;
+ memInfos.add(mi);
+ }
+ }
+ }
+ }
+ }
+
+ long totalPss = 0;
+ for (int i=0, N=memInfos.size(); i<N; i++) {
+ ProcessMemInfo mi = memInfos.get(i);
+ if (mi.pss == 0) {
+ mi.pss = Debug.getPss(mi.pid, null);
+ }
+ totalPss += mi.pss;
+ }
+ Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
+ @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
+ if (lhs.oomAdj != rhs.oomAdj) {
+ return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
+ }
+ if (lhs.pss != rhs.pss) {
+ return lhs.pss < rhs.pss ? 1 : -1;
+ }
+ return 0;
+ }
+ });
+
+ StringBuilder tag = new StringBuilder(128);
+ StringBuilder stack = new StringBuilder(128);
+ tag.append("Low on memory -- ");
+ appendMemBucket(tag, totalPss, "total", false);
+ appendMemBucket(stack, totalPss, "total", true);
+
+ StringBuilder fullNativeBuilder = new StringBuilder(1024);
+ StringBuilder shortNativeBuilder = new StringBuilder(1024);
+ StringBuilder fullJavaBuilder = new StringBuilder(1024);
+
+ boolean firstLine = true;
+ int lastOomAdj = Integer.MIN_VALUE;
+ long extraNativeRam = 0;
+ long cachedPss = 0;
+ for (int i=0, N=memInfos.size(); i<N; i++) {
+ ProcessMemInfo mi = memInfos.get(i);
+
+ if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
+ cachedPss += mi.pss;
+ }
+
+ if (mi.oomAdj != ProcessList.NATIVE_ADJ
+ && (mi.oomAdj < ProcessList.SERVICE_ADJ
+ || mi.oomAdj == ProcessList.HOME_APP_ADJ
+ || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
+ if (lastOomAdj != mi.oomAdj) {
+ lastOomAdj = mi.oomAdj;
+ if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
+ tag.append(" / ");
+ }
+ if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
+ if (firstLine) {
+ stack.append(":");
+ firstLine = false;
+ }
+ stack.append("\n\t at ");
+ } else {
+ stack.append("$");
+ }
+ } else {
+ tag.append(" ");
+ stack.append("$");
+ }
+ if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
+ appendMemBucket(tag, mi.pss, mi.name, false);
+ }
+ appendMemBucket(stack, mi.pss, mi.name, true);
+ if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
+ && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
+ stack.append("(");
+ for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
+ if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
+ stack.append(DUMP_MEM_OOM_LABEL[k]);
+ stack.append(":");
+ stack.append(DUMP_MEM_OOM_ADJ[k]);
+ }
+ }
+ stack.append(")");
+ }
+ }
+
+ appendMemInfo(fullNativeBuilder, mi);
+ if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
+ // The short form only has native processes that are >= 1MB.
+ if (mi.pss >= 1000) {
+ appendMemInfo(shortNativeBuilder, mi);
+ } else {
+ extraNativeRam += mi.pss;
+ }
+ } else {
+ // Short form has all other details, but if we have collected RAM
+ // from smaller native processes let's dump a summary of that.
+ if (extraNativeRam > 0) {
+ appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
+ -1, extraNativeRam, "(Other native)");
+ shortNativeBuilder.append('\n');
+ extraNativeRam = 0;
+ }
+ appendMemInfo(fullJavaBuilder, mi);
+ }
+ }
+
+ fullJavaBuilder.append(" ");
+ ProcessList.appendRamKb(fullJavaBuilder, totalPss);
+ fullJavaBuilder.append(" kB: TOTAL\n");
+
+ MemInfoReader memInfo = new MemInfoReader();
+ memInfo.readMemInfo();
+ final long[] infos = memInfo.getRawInfo();
+
+ StringBuilder memInfoBuilder = new StringBuilder(1024);
+ Debug.getMemInfo(infos);
+ memInfoBuilder.append(" MemInfo: ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
+ memInfoBuilder.append(" ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
+ if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
+ memInfoBuilder.append(" ZRAM: ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
+ memInfoBuilder.append(" kB RAM, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
+ memInfoBuilder.append(" kB swap total, ");
+ memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
+ memInfoBuilder.append(" kB swap free\n");
+ }
+ final long[] ksm = getKsmInfo();
+ if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
+ || ksm[KSM_VOLATILE] != 0) {
+ memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
+ memInfoBuilder.append(" kB saved from shared ");
+ memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
+ memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
+ memInfoBuilder.append(" kB unshared; ");
+ memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
+ }
+ memInfoBuilder.append(" Free RAM: ");
+ memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
+ + memInfo.getFreeSizeKb());
+ memInfoBuilder.append(" kB\n");
+ memInfoBuilder.append(" Used RAM: ");
+ memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
+ memInfoBuilder.append(" kB\n");
+ memInfoBuilder.append(" Lost RAM: ");
+ memInfoBuilder.append(memInfo.getTotalSizeKb()
+ - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
+ - memInfo.getKernelUsedSizeKb());
+ memInfoBuilder.append(" kB\n");
+ Slog.i(TAG, "Low on memory:");
+ Slog.i(TAG, shortNativeBuilder.toString());
+ Slog.i(TAG, fullJavaBuilder.toString());
+ Slog.i(TAG, memInfoBuilder.toString());
+
+ StringBuilder dropBuilder = new StringBuilder(1024);
+ /*
+ StringWriter oomSw = new StringWriter();
+ PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
+ StringWriter catSw = new StringWriter();
+ PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
+ String[] emptyArgs = new String[] { };
+ dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
+ oomPw.flush();
+ String oomString = oomSw.toString();
+ */
+ dropBuilder.append("Low on memory:");
+ dropBuilder.append(stack);
+ dropBuilder.append('\n');
+ dropBuilder.append(fullNativeBuilder);
+ dropBuilder.append(fullJavaBuilder);
+ dropBuilder.append('\n');
+ dropBuilder.append(memInfoBuilder);
+ dropBuilder.append('\n');
+ /*
+ dropBuilder.append(oomString);
+ dropBuilder.append('\n');
+ */
+ StringWriter catSw = new StringWriter();
+ synchronized (ActivityManagerService.this) {
+ PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
+ String[] emptyArgs = new String[] { };
+ catPw.println();
+ dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
+ catPw.println();
+ mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
+ false, false, null);
+ catPw.println();
+ dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
+ catPw.flush();
+ }
+ dropBuilder.append(catSw.toString());
+ addErrorToDropBox("lowmem", null, "system_server", null,
+ null, tag.toString(), dropBuilder.toString(), null, null);
+ //Slog.i(TAG, "Sent to dropbox:");
+ //Slog.i(TAG, dropBuilder.toString());
+ synchronized (ActivityManagerService.this) {
+ long now = SystemClock.uptimeMillis();
+ if (mLastMemUsageReportTime < now) {
+ mLastMemUsageReportTime = now;
+ }
+ }
+ }
+
/**
* Searches array of arguments for the specified string
* @param args array of argument strings