Loading services/core/java/com/android/server/stats/pull/ProcfsMemoryUtil.java +10 −5 Original line number Diff line number Diff line Loading @@ -19,8 +19,7 @@ import static android.os.Process.PROC_OUT_STRING; import android.annotation.Nullable; import android.os.Process; import java.util.function.BiConsumer; import android.util.SparseArray; public final class ProcfsMemoryUtil { private static final int[] CMDLINE_OUT = new int[] { PROC_OUT_STRING }; Loading Loading @@ -71,19 +70,25 @@ public final class ProcfsMemoryUtil { return cmdline[0]; } public static void forEachPid(BiConsumer<Integer, String> func) { /** * Scans all /proc/pid/cmdline entries and returns a mapping between pid and cmdline. */ public static SparseArray<String> getProcessCmdlines() { int[] pids = new int[1024]; pids = Process.getPids("/proc", pids); SparseArray<String> cmdlines = new SparseArray<>(pids.length); for (int pid : pids) { if (pid < 0) { return; break; } String cmdline = readCmdlineFromProcfs(pid); if (cmdline.isEmpty()) { continue; } func.accept(pid, cmdline); cmdlines.append(pid, cmdline); } return cmdlines; } public static final class MemorySnapshot { Loading services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +24 −63 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ import static android.os.storage.VolumeInfo.TYPE_PUBLIC; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; import static com.android.server.stats.pull.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs; import static com.android.server.stats.pull.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs; import static com.android.server.stats.pull.ProcfsMemoryUtil.forEachPid; import static com.android.server.stats.pull.ProcfsMemoryUtil.getProcessCmdlines; import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs; import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs; Loading Loading @@ -93,6 +93,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.util.StatsEvent; import android.util.StatsLog; import android.util.proto.ProtoOutputStream; Loading Loading @@ -130,8 +131,6 @@ import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot; import com.android.server.storage.DiskStatsFileLogger; import com.android.server.storage.DiskStatsLoggingService; import com.google.android.collect.Sets; import libcore.io.IoUtils; import org.json.JSONArray; Loading Loading @@ -1147,37 +1146,6 @@ public class StatsPullAtomService extends SystemService { return StatsManager.PULL_SUCCESS; } /** * Which native processes to snapshot memory for. * * <p>Processes are matched by their cmdline in procfs. Example: cat /proc/pid/cmdline returns * /system/bin/statsd for the stats daemon. */ private static final Set<String> MEMORY_INTERESTING_NATIVE_PROCESSES = Sets.newHashSet( "/system/bin/statsd", // Stats daemon. "/system/bin/surfaceflinger", "/system/bin/apexd", // APEX daemon. "/system/bin/audioserver", "/system/bin/cameraserver", "/system/bin/drmserver", "/system/bin/healthd", "/system/bin/incidentd", "/system/bin/installd", "/system/bin/lmkd", // Low memory killer daemon. "/system/bin/logd", "media.codec", "media.extractor", "media.metrics", "/system/bin/mediadrmserver", "/system/bin/mediaserver", "/system/bin/performanced", "/system/bin/tombstoned", "/system/bin/traced", // Perfetto. "/system/bin/traced_probes", // Perfetto. "webview_zygote", "zygote", "zygote64"); /** * Lowest available uid for apps. * Loading Loading @@ -1219,30 +1187,25 @@ public class StatsPullAtomService extends SystemService { .build(); pulledData.add(e); } forEachPid((pid, cmdLine) -> { if (!MEMORY_INTERESTING_NATIVE_PROCESSES.contains(cmdLine)) { return; } final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid); if (snapshot == null) { return; } // Sometimes we get here a process that is not included in the whitelist. It comes // from forking the zygote for an app. We can ignore that sample because this process // is collected by ProcessMemoryState. if (isAppUid(snapshot.uid)) { return; // Complement the data with native system processes SparseArray<String> processCmdlines = getProcessCmdlines(); managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid)); int size = processCmdlines.size(); for (int i = 0; i < size; ++i) { final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(processCmdlines.keyAt(i)); if (snapshot == null || isAppUid(snapshot.uid)) { continue; } StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) .writeInt(snapshot.uid) .writeString(cmdLine) .writeString(processCmdlines.valueAt(i)) // RSS high-water mark in bytes. .writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L) .writeInt(snapshot.rssHighWaterMarkInKilobytes) .build(); pulledData.add(e); }); } // Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes. SystemProperties.set("sys.rss_hwm_reset.on", "1"); return StatsManager.PULL_SUCCESS; Loading Loading @@ -1280,24 +1243,22 @@ public class StatsPullAtomService extends SystemService { .build(); pulledData.add(e); } forEachPid((pid, cmdLine) -> { if (!MEMORY_INTERESTING_NATIVE_PROCESSES.contains(cmdLine)) { return; } // Complement the data with native system processes. Given these measurements can be taken // in response to LMKs happening, we want to first collect the managed app stats (to // maximize the probability that a heavyweight process will be sampled before it dies). SparseArray<String> processCmdlines = getProcessCmdlines(); managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid)); int size = processCmdlines.size(); for (int i = 0; i < size; ++i) { int pid = processCmdlines.keyAt(i); final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid); if (snapshot == null) { return; } // Sometimes we get here a process that is not included in the whitelist. It comes // from forking the zygote for an app. We can ignore that sample because this process // is collected by ProcessMemoryState. if (isAppUid(snapshot.uid)) { return; if (snapshot == null || isAppUid(snapshot.uid)) { continue; } StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) .writeInt(snapshot.uid) .writeString(cmdLine) .writeString(processCmdlines.valueAt(i)) .writeInt(pid) .writeInt(-1001) // Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1. .writeInt(snapshot.rssInKilobytes) Loading @@ -1306,7 +1267,7 @@ public class StatsPullAtomService extends SystemService { .writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes) .build(); pulledData.add(e); }); } return StatsManager.PULL_SUCCESS; } Loading Loading
services/core/java/com/android/server/stats/pull/ProcfsMemoryUtil.java +10 −5 Original line number Diff line number Diff line Loading @@ -19,8 +19,7 @@ import static android.os.Process.PROC_OUT_STRING; import android.annotation.Nullable; import android.os.Process; import java.util.function.BiConsumer; import android.util.SparseArray; public final class ProcfsMemoryUtil { private static final int[] CMDLINE_OUT = new int[] { PROC_OUT_STRING }; Loading Loading @@ -71,19 +70,25 @@ public final class ProcfsMemoryUtil { return cmdline[0]; } public static void forEachPid(BiConsumer<Integer, String> func) { /** * Scans all /proc/pid/cmdline entries and returns a mapping between pid and cmdline. */ public static SparseArray<String> getProcessCmdlines() { int[] pids = new int[1024]; pids = Process.getPids("/proc", pids); SparseArray<String> cmdlines = new SparseArray<>(pids.length); for (int pid : pids) { if (pid < 0) { return; break; } String cmdline = readCmdlineFromProcfs(pid); if (cmdline.isEmpty()) { continue; } func.accept(pid, cmdline); cmdlines.append(pid, cmdline); } return cmdlines; } public static final class MemorySnapshot { Loading
services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +24 −63 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ import static android.os.storage.VolumeInfo.TYPE_PUBLIC; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; import static com.android.server.stats.pull.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs; import static com.android.server.stats.pull.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs; import static com.android.server.stats.pull.ProcfsMemoryUtil.forEachPid; import static com.android.server.stats.pull.ProcfsMemoryUtil.getProcessCmdlines; import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs; import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs; Loading Loading @@ -93,6 +93,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.util.StatsEvent; import android.util.StatsLog; import android.util.proto.ProtoOutputStream; Loading Loading @@ -130,8 +131,6 @@ import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot; import com.android.server.storage.DiskStatsFileLogger; import com.android.server.storage.DiskStatsLoggingService; import com.google.android.collect.Sets; import libcore.io.IoUtils; import org.json.JSONArray; Loading Loading @@ -1147,37 +1146,6 @@ public class StatsPullAtomService extends SystemService { return StatsManager.PULL_SUCCESS; } /** * Which native processes to snapshot memory for. * * <p>Processes are matched by their cmdline in procfs. Example: cat /proc/pid/cmdline returns * /system/bin/statsd for the stats daemon. */ private static final Set<String> MEMORY_INTERESTING_NATIVE_PROCESSES = Sets.newHashSet( "/system/bin/statsd", // Stats daemon. "/system/bin/surfaceflinger", "/system/bin/apexd", // APEX daemon. "/system/bin/audioserver", "/system/bin/cameraserver", "/system/bin/drmserver", "/system/bin/healthd", "/system/bin/incidentd", "/system/bin/installd", "/system/bin/lmkd", // Low memory killer daemon. "/system/bin/logd", "media.codec", "media.extractor", "media.metrics", "/system/bin/mediadrmserver", "/system/bin/mediaserver", "/system/bin/performanced", "/system/bin/tombstoned", "/system/bin/traced", // Perfetto. "/system/bin/traced_probes", // Perfetto. "webview_zygote", "zygote", "zygote64"); /** * Lowest available uid for apps. * Loading Loading @@ -1219,30 +1187,25 @@ public class StatsPullAtomService extends SystemService { .build(); pulledData.add(e); } forEachPid((pid, cmdLine) -> { if (!MEMORY_INTERESTING_NATIVE_PROCESSES.contains(cmdLine)) { return; } final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid); if (snapshot == null) { return; } // Sometimes we get here a process that is not included in the whitelist. It comes // from forking the zygote for an app. We can ignore that sample because this process // is collected by ProcessMemoryState. if (isAppUid(snapshot.uid)) { return; // Complement the data with native system processes SparseArray<String> processCmdlines = getProcessCmdlines(); managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid)); int size = processCmdlines.size(); for (int i = 0; i < size; ++i) { final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(processCmdlines.keyAt(i)); if (snapshot == null || isAppUid(snapshot.uid)) { continue; } StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) .writeInt(snapshot.uid) .writeString(cmdLine) .writeString(processCmdlines.valueAt(i)) // RSS high-water mark in bytes. .writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L) .writeInt(snapshot.rssHighWaterMarkInKilobytes) .build(); pulledData.add(e); }); } // Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes. SystemProperties.set("sys.rss_hwm_reset.on", "1"); return StatsManager.PULL_SUCCESS; Loading Loading @@ -1280,24 +1243,22 @@ public class StatsPullAtomService extends SystemService { .build(); pulledData.add(e); } forEachPid((pid, cmdLine) -> { if (!MEMORY_INTERESTING_NATIVE_PROCESSES.contains(cmdLine)) { return; } // Complement the data with native system processes. Given these measurements can be taken // in response to LMKs happening, we want to first collect the managed app stats (to // maximize the probability that a heavyweight process will be sampled before it dies). SparseArray<String> processCmdlines = getProcessCmdlines(); managedProcessList.forEach(managedProcess -> processCmdlines.delete(managedProcess.pid)); int size = processCmdlines.size(); for (int i = 0; i < size; ++i) { int pid = processCmdlines.keyAt(i); final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid); if (snapshot == null) { return; } // Sometimes we get here a process that is not included in the whitelist. It comes // from forking the zygote for an app. We can ignore that sample because this process // is collected by ProcessMemoryState. if (isAppUid(snapshot.uid)) { return; if (snapshot == null || isAppUid(snapshot.uid)) { continue; } StatsEvent e = StatsEvent.newBuilder() .setAtomId(atomTag) .writeInt(snapshot.uid) .writeString(cmdLine) .writeString(processCmdlines.valueAt(i)) .writeInt(pid) .writeInt(-1001) // Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1. .writeInt(snapshot.rssInKilobytes) Loading @@ -1306,7 +1267,7 @@ public class StatsPullAtomService extends SystemService { .writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes) .build(); pulledData.add(e); }); } return StatsManager.PULL_SUCCESS; } Loading