diff options
author | Dianne Hackborn <hackbod@google.com> | 2014-10-31 22:44:23 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-10-31 22:44:24 +0000 |
commit | f34fa3e7aa9be9bf24c955a9ebf34022e4b88c25 (patch) | |
tree | ba984c30ae6e607d34a907a3ddf4b01743b77c26 | |
parent | 30e5113000877e053ba4f30b5962a42a4d11fa6e (diff) | |
parent | 6edb5c665dcb024ae7cfb95b9a92e30dcc5777c1 (diff) | |
download | frameworks_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.java | 4 | ||||
-rwxr-xr-x | services/core/java/com/android/server/am/ActivityManagerService.java | 520 |
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 |