Loading core/java/android/os/Debug.java +6 −1 Original line number Diff line number Diff line Loading @@ -1888,10 +1888,13 @@ public final class Debug /** * Note: currently only works when the requested pid has the same UID * as the caller. * * @return true if the meminfo was read successfully, false if not (i.e., given pid has gone). * * @hide */ @UnsupportedAppUsage public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo); public static native boolean getMemoryInfo(int pid, MemoryInfo memoryInfo); /** * Retrieves the PSS memory used by the process as given by the Loading @@ -1904,6 +1907,8 @@ public final class Debug * array of up to 3 entries to also receive (up to 3 values in order): the Uss and SwapPss and * Rss (only filled in as of {@link android.os.Build.VERSION_CODES#P}) of the process, and * another array to also retrieve the separate memtrack size. * * @return The PSS memory usage, or 0 if failed to retrieve (i.e., given pid has gone). * @hide */ public static native long getPss(int pid, long[] outUssSwapPssRss, long[] outMemtrack); Loading core/jni/android_os_Debug.cpp +11 −6 Original line number Diff line number Diff line Loading @@ -237,7 +237,7 @@ static int read_memtrack_memory(int pid, struct graphics_memory_pss* graphics_me return err; } static void load_maps(int pid, stats_t* stats, bool* foundSwapPss) static bool load_maps(int pid, stats_t* stats, bool* foundSwapPss) { *foundSwapPss = false; uint64_t prev_end = 0; Loading Loading @@ -407,17 +407,19 @@ static void load_maps(int pid, stats_t* stats, bool* foundSwapPss) } }; meminfo::ForEachVmaFromFile(smaps_path, vma_scan); return meminfo::ForEachVmaFromFile(smaps_path, vma_scan); } static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, static jboolean android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, jint pid, jobject object) { bool foundSwapPss; stats_t stats[_NUM_HEAP]; memset(&stats, 0, sizeof(stats)); load_maps(pid, stats, &foundSwapPss); if (!load_maps(pid, stats, &foundSwapPss)) { return JNI_FALSE; } struct graphics_memory_pss graphics_mem; if (read_memtrack_memory(pid, &graphics_mem) == 0) { Loading Loading @@ -462,7 +464,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0); if (otherArray == NULL) { return; return JNI_FALSE; } int j=0; Loading @@ -479,6 +481,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, } env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0); return JNI_TRUE; } static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object) Loading Loading @@ -508,6 +511,8 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, rss += stats.rss; swapPss = stats.swap_pss; pss += swapPss; // Also in swap, those pages would be accounted as Pss without SWAP } else { return 0; } if (outUssSwapPssRss != NULL) { Loading Loading @@ -866,7 +871,7 @@ static const JNINativeMethod gMethods[] = { (void*) android_os_Debug_getNativeHeapFreeSize }, { "getMemoryInfo", "(Landroid/os/Debug$MemoryInfo;)V", (void*) android_os_Debug_getDirtyPages }, { "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)V", { "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)Z", (void*) android_os_Debug_getDirtyPagesPid }, { "getPss", "()J", (void*) android_os_Debug_getPss }, Loading services/core/java/com/android/server/am/ActivityManagerService.java +72 −29 Original line number Diff line number Diff line Loading @@ -12594,7 +12594,7 @@ public class ActivityManagerService extends IActivityManager.Stub ArrayList<ProcessRecord> procs, PrintWriter categoryPw) { long uptime = SystemClock.uptimeMillis(); long realtime = SystemClock.elapsedRealtime(); final long[] tmpLong = new long[1]; final long[] tmpLong = new long[3]; if (procs == null) { // No Java processes. Maybe they want to print a native process. Loading Loading @@ -12627,17 +12627,25 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { final ProcessCpuTracker.Stats r = nativeProcs.get(i); final int pid = r.pid; if (!opts.isCheckinRequest && opts.dumpDetails) { pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); } if (mi == null) { mi = new Debug.MemoryInfo(); } if (opts.dumpDetails || (!brief && !opts.oomOnly)) { Debug.getMemoryInfo(pid, mi); if (!Debug.getMemoryInfo(pid, mi)) { continue; } } else { mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); mi.dalvikPrivateDirty = (int)tmpLong[0]; long pss = Debug.getPss(pid, tmpLong, null); if (pss == 0) { continue; } mi.nativePss = (int) pss; mi.nativePrivateDirty = (int) tmpLong[0]; mi.nativeRss = (int) tmpLong[2]; } if (!opts.isCheckinRequest && opts.dumpDetails) { pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); } ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly, Loading Loading @@ -12715,9 +12723,6 @@ public class ActivityManagerService extends IActivityManager.Stub hasActivities = r.hasActivities(); } if (thread != null) { if (!opts.isCheckinRequest && opts.dumpDetails) { pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); } if (mi == null) { mi = new Debug.MemoryInfo(); } Loading @@ -12727,17 +12732,26 @@ public class ActivityManagerService extends IActivityManager.Stub if (opts.dumpDetails || (!brief && !opts.oomOnly)) { reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW; startTime = SystemClock.currentThreadTimeMillis(); Debug.getMemoryInfo(pid, mi); if (!Debug.getMemoryInfo(pid, mi)) { continue; } endTime = SystemClock.currentThreadTimeMillis(); hasSwapPss = mi.hasSwappedOutPss; } else { reportType = ProcessStats.ADD_PSS_EXTERNAL; startTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); long pss = Debug.getPss(pid, tmpLong, null); if (pss == 0) { continue; } mi.dalvikPss = (int) pss; endTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPrivateDirty = (int) tmpLong[0]; mi.dalvikRss = (int) tmpLong[2]; } if (!opts.isCheckinRequest && opts.dumpDetails) { pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); } if (opts.dumpDetails) { if (opts.localOnly) { ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails, Loading Loading @@ -12867,10 +12881,17 @@ public class ActivityManagerService extends IActivityManager.Stub mi = new Debug.MemoryInfo(); } if (!brief && !opts.oomOnly) { Debug.getMemoryInfo(st.pid, mi); if (!Debug.getMemoryInfo(st.pid, mi)) { continue; } } else { mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); long pss = Debug.getPss(st.pid, tmpLong, null); if (pss == 0) { continue; } mi.nativePss = (int) pss; mi.nativePrivateDirty = (int) tmpLong[0]; mi.nativeRss = (int) tmpLong[2]; } final long myTotalPss = mi.getTotalPss(); Loading Loading @@ -13174,7 +13195,7 @@ public class ActivityManagerService extends IActivityManager.Stub ArrayList<ProcessRecord> procs) { final long uptimeMs = SystemClock.uptimeMillis(); final long realtimeMs = SystemClock.elapsedRealtime(); final long[] tmpLong = new long[1]; final long[] tmpLong = new long[3]; if (procs == null) { // No Java processes. Maybe they want to print a native process. Loading Loading @@ -13209,20 +13230,29 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { final ProcessCpuTracker.Stats r = nativeProcs.get(i); final int pid = r.pid; final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES); proto.write(MemInfoDumpProto.ProcessMemory.PID, pid); proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName); if (mi == null) { mi = new Debug.MemoryInfo(); } if (opts.dumpDetails || (!brief && !opts.oomOnly)) { Debug.getMemoryInfo(pid, mi); if (!Debug.getMemoryInfo(pid, mi)) { continue; } } else { mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); mi.dalvikPrivateDirty = (int)tmpLong[0]; long pss = Debug.getPss(pid, tmpLong, null); if (pss == 0) { continue; } mi.nativePss = (int) pss; mi.nativePrivateDirty = (int) tmpLong[0]; mi.nativeRss = (int) tmpLong[2]; } final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES); proto.write(MemInfoDumpProto.ProcessMemory.PID, pid); proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName); ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik, opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0); Loading Loading @@ -13313,13 +13343,19 @@ public class ActivityManagerService extends IActivityManager.Stub if (opts.dumpDetails || (!brief && !opts.oomOnly)) { reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW; startTime = SystemClock.currentThreadTimeMillis(); Debug.getMemoryInfo(pid, mi); if (!Debug.getMemoryInfo(pid, mi)) { continue; } endTime = SystemClock.currentThreadTimeMillis(); hasSwapPss = mi.hasSwappedOutPss; } else { reportType = ProcessStats.ADD_PSS_EXTERNAL; startTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null); long pss = Debug.getPss(pid, tmpLong, null); if (pss == 0) { continue; } mi.dalvikPss = (int) pss; endTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPrivateDirty = (int) tmpLong[0]; mi.dalvikRss = (int) tmpLong[2]; Loading Loading @@ -13447,10 +13483,17 @@ public class ActivityManagerService extends IActivityManager.Stub mi = new Debug.MemoryInfo(); } if (!brief && !opts.oomOnly) { Debug.getMemoryInfo(st.pid, mi); if (!Debug.getMemoryInfo(st.pid, mi)) { continue; } } else { mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); long pss = Debug.getPss(st.pid, tmpLong, null); if (pss == 0) { continue; } mi.nativePss = (int) pss; mi.nativePrivateDirty = (int) tmpLong[0]; mi.nativeRss = (int) tmpLong[2]; } final long myTotalPss = mi.getTotalPss(); Loading
core/java/android/os/Debug.java +6 −1 Original line number Diff line number Diff line Loading @@ -1888,10 +1888,13 @@ public final class Debug /** * Note: currently only works when the requested pid has the same UID * as the caller. * * @return true if the meminfo was read successfully, false if not (i.e., given pid has gone). * * @hide */ @UnsupportedAppUsage public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo); public static native boolean getMemoryInfo(int pid, MemoryInfo memoryInfo); /** * Retrieves the PSS memory used by the process as given by the Loading @@ -1904,6 +1907,8 @@ public final class Debug * array of up to 3 entries to also receive (up to 3 values in order): the Uss and SwapPss and * Rss (only filled in as of {@link android.os.Build.VERSION_CODES#P}) of the process, and * another array to also retrieve the separate memtrack size. * * @return The PSS memory usage, or 0 if failed to retrieve (i.e., given pid has gone). * @hide */ public static native long getPss(int pid, long[] outUssSwapPssRss, long[] outMemtrack); Loading
core/jni/android_os_Debug.cpp +11 −6 Original line number Diff line number Diff line Loading @@ -237,7 +237,7 @@ static int read_memtrack_memory(int pid, struct graphics_memory_pss* graphics_me return err; } static void load_maps(int pid, stats_t* stats, bool* foundSwapPss) static bool load_maps(int pid, stats_t* stats, bool* foundSwapPss) { *foundSwapPss = false; uint64_t prev_end = 0; Loading Loading @@ -407,17 +407,19 @@ static void load_maps(int pid, stats_t* stats, bool* foundSwapPss) } }; meminfo::ForEachVmaFromFile(smaps_path, vma_scan); return meminfo::ForEachVmaFromFile(smaps_path, vma_scan); } static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, static jboolean android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, jint pid, jobject object) { bool foundSwapPss; stats_t stats[_NUM_HEAP]; memset(&stats, 0, sizeof(stats)); load_maps(pid, stats, &foundSwapPss); if (!load_maps(pid, stats, &foundSwapPss)) { return JNI_FALSE; } struct graphics_memory_pss graphics_mem; if (read_memtrack_memory(pid, &graphics_mem) == 0) { Loading Loading @@ -462,7 +464,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0); if (otherArray == NULL) { return; return JNI_FALSE; } int j=0; Loading @@ -479,6 +481,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, } env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0); return JNI_TRUE; } static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object) Loading Loading @@ -508,6 +511,8 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, rss += stats.rss; swapPss = stats.swap_pss; pss += swapPss; // Also in swap, those pages would be accounted as Pss without SWAP } else { return 0; } if (outUssSwapPssRss != NULL) { Loading Loading @@ -866,7 +871,7 @@ static const JNINativeMethod gMethods[] = { (void*) android_os_Debug_getNativeHeapFreeSize }, { "getMemoryInfo", "(Landroid/os/Debug$MemoryInfo;)V", (void*) android_os_Debug_getDirtyPages }, { "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)V", { "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)Z", (void*) android_os_Debug_getDirtyPagesPid }, { "getPss", "()J", (void*) android_os_Debug_getPss }, Loading
services/core/java/com/android/server/am/ActivityManagerService.java +72 −29 Original line number Diff line number Diff line Loading @@ -12594,7 +12594,7 @@ public class ActivityManagerService extends IActivityManager.Stub ArrayList<ProcessRecord> procs, PrintWriter categoryPw) { long uptime = SystemClock.uptimeMillis(); long realtime = SystemClock.elapsedRealtime(); final long[] tmpLong = new long[1]; final long[] tmpLong = new long[3]; if (procs == null) { // No Java processes. Maybe they want to print a native process. Loading Loading @@ -12627,17 +12627,25 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { final ProcessCpuTracker.Stats r = nativeProcs.get(i); final int pid = r.pid; if (!opts.isCheckinRequest && opts.dumpDetails) { pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); } if (mi == null) { mi = new Debug.MemoryInfo(); } if (opts.dumpDetails || (!brief && !opts.oomOnly)) { Debug.getMemoryInfo(pid, mi); if (!Debug.getMemoryInfo(pid, mi)) { continue; } } else { mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); mi.dalvikPrivateDirty = (int)tmpLong[0]; long pss = Debug.getPss(pid, tmpLong, null); if (pss == 0) { continue; } mi.nativePss = (int) pss; mi.nativePrivateDirty = (int) tmpLong[0]; mi.nativeRss = (int) tmpLong[2]; } if (!opts.isCheckinRequest && opts.dumpDetails) { pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); } ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly, Loading Loading @@ -12715,9 +12723,6 @@ public class ActivityManagerService extends IActivityManager.Stub hasActivities = r.hasActivities(); } if (thread != null) { if (!opts.isCheckinRequest && opts.dumpDetails) { pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); } if (mi == null) { mi = new Debug.MemoryInfo(); } Loading @@ -12727,17 +12732,26 @@ public class ActivityManagerService extends IActivityManager.Stub if (opts.dumpDetails || (!brief && !opts.oomOnly)) { reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW; startTime = SystemClock.currentThreadTimeMillis(); Debug.getMemoryInfo(pid, mi); if (!Debug.getMemoryInfo(pid, mi)) { continue; } endTime = SystemClock.currentThreadTimeMillis(); hasSwapPss = mi.hasSwappedOutPss; } else { reportType = ProcessStats.ADD_PSS_EXTERNAL; startTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); long pss = Debug.getPss(pid, tmpLong, null); if (pss == 0) { continue; } mi.dalvikPss = (int) pss; endTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPrivateDirty = (int) tmpLong[0]; mi.dalvikRss = (int) tmpLong[2]; } if (!opts.isCheckinRequest && opts.dumpDetails) { pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); } if (opts.dumpDetails) { if (opts.localOnly) { ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails, Loading Loading @@ -12867,10 +12881,17 @@ public class ActivityManagerService extends IActivityManager.Stub mi = new Debug.MemoryInfo(); } if (!brief && !opts.oomOnly) { Debug.getMemoryInfo(st.pid, mi); if (!Debug.getMemoryInfo(st.pid, mi)) { continue; } } else { mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); long pss = Debug.getPss(st.pid, tmpLong, null); if (pss == 0) { continue; } mi.nativePss = (int) pss; mi.nativePrivateDirty = (int) tmpLong[0]; mi.nativeRss = (int) tmpLong[2]; } final long myTotalPss = mi.getTotalPss(); Loading Loading @@ -13174,7 +13195,7 @@ public class ActivityManagerService extends IActivityManager.Stub ArrayList<ProcessRecord> procs) { final long uptimeMs = SystemClock.uptimeMillis(); final long realtimeMs = SystemClock.elapsedRealtime(); final long[] tmpLong = new long[1]; final long[] tmpLong = new long[3]; if (procs == null) { // No Java processes. Maybe they want to print a native process. Loading Loading @@ -13209,20 +13230,29 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { final ProcessCpuTracker.Stats r = nativeProcs.get(i); final int pid = r.pid; final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES); proto.write(MemInfoDumpProto.ProcessMemory.PID, pid); proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName); if (mi == null) { mi = new Debug.MemoryInfo(); } if (opts.dumpDetails || (!brief && !opts.oomOnly)) { Debug.getMemoryInfo(pid, mi); if (!Debug.getMemoryInfo(pid, mi)) { continue; } } else { mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); mi.dalvikPrivateDirty = (int)tmpLong[0]; long pss = Debug.getPss(pid, tmpLong, null); if (pss == 0) { continue; } mi.nativePss = (int) pss; mi.nativePrivateDirty = (int) tmpLong[0]; mi.nativeRss = (int) tmpLong[2]; } final long nToken = proto.start(MemInfoDumpProto.NATIVE_PROCESSES); proto.write(MemInfoDumpProto.ProcessMemory.PID, pid); proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME, r.baseName); ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik, opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0); Loading Loading @@ -13313,13 +13343,19 @@ public class ActivityManagerService extends IActivityManager.Stub if (opts.dumpDetails || (!brief && !opts.oomOnly)) { reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW; startTime = SystemClock.currentThreadTimeMillis(); Debug.getMemoryInfo(pid, mi); if (!Debug.getMemoryInfo(pid, mi)) { continue; } endTime = SystemClock.currentThreadTimeMillis(); hasSwapPss = mi.hasSwappedOutPss; } else { reportType = ProcessStats.ADD_PSS_EXTERNAL; startTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null); long pss = Debug.getPss(pid, tmpLong, null); if (pss == 0) { continue; } mi.dalvikPss = (int) pss; endTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPrivateDirty = (int) tmpLong[0]; mi.dalvikRss = (int) tmpLong[2]; Loading Loading @@ -13447,10 +13483,17 @@ public class ActivityManagerService extends IActivityManager.Stub mi = new Debug.MemoryInfo(); } if (!brief && !opts.oomOnly) { Debug.getMemoryInfo(st.pid, mi); if (!Debug.getMemoryInfo(st.pid, mi)) { continue; } } else { mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); long pss = Debug.getPss(st.pid, tmpLong, null); if (pss == 0) { continue; } mi.nativePss = (int) pss; mi.nativePrivateDirty = (int) tmpLong[0]; mi.nativeRss = (int) tmpLong[2]; } final long myTotalPss = mi.getTotalPss();