Loading cmds/statsd/src/atoms.proto +10 −48 Original line number Diff line number Diff line Loading @@ -378,7 +378,6 @@ message Atom { PowerProfile power_profile = 10033; ProcStatsPkgProc proc_stats_pkg_proc = 10034; ProcessCpuTime process_cpu_time = 10035; NativeProcessMemoryState native_process_memory_state = 10036; CpuTimePerThreadFreq cpu_time_per_thread_freq = 10037; OnDevicePowerMeasurement on_device_power_measurement = 10038; DeviceCalculatedPowerUse device_calculated_power_use = 10039; Loading Loading @@ -412,6 +411,8 @@ message Atom { // DO NOT USE field numbers above 100,000 in AOSP. // Field numbers 100,000 - 199,999 are reserved for non-AOSP (e.g. OEMs) to use. // Field numbers 200,000 and above are reserved for future use; do not use them at all. reserved 10036; } /** Loading Loading @@ -4019,8 +4020,8 @@ message ProcessMemoryState { optional int64 page_major_fault = 5; // RSS // Value is read from /proc/PID/status. Or from memory.stat, field // total_rss if per-app memory cgroups are enabled. // Value is read from memory.stat, field total_rss if per-app memory // cgroups are enabled. Otherwise, value from /proc/pid/stat. optional int64 rss_in_bytes = 6; // CACHE Loading @@ -4030,56 +4031,17 @@ message ProcessMemoryState { // SWAP // Value is read from memory.stat, field total_swap if per-app memory // cgroups are enabled. Otherwise, VmSwap from /proc/PID/status. // cgroups are enabled. Otherwise, 0. optional int64 swap_in_bytes = 8; // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always 0. // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always -1. optional int64 rss_high_watermark_in_bytes = 9 [deprecated = true]; // Elapsed real time when the process started. // Value is read from /proc/PID/stat, field 22. 0 if read from per-app memory cgroups. optional int64 start_time_nanos = 10; // Anonymous page size plus swap size. Values are read from /proc/PID/status. optional int32 anon_rss_and_swap_in_kilobytes = 11; } /* * Logs the memory stats for a native process (from procfs). * * Pulled from StatsCompanionService for selected native processes. */ message NativeProcessMemoryState { // The uid if available. -1 means not available. optional int32 uid = 1 [(is_uid) = true]; // The process name. // Value read from /proc/PID/cmdline. optional string process_name = 2; // # of page-faults optional int64 page_fault = 3; // # of major page-faults optional int64 page_major_fault = 4; // RSS // Value read from /proc/PID/status. optional int64 rss_in_bytes = 5; // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always 0. optional int64 rss_high_watermark_in_bytes = 6 [deprecated = true]; // Elapsed real time when the process started. // Value is read from /proc/PID/stat, field 22. optional int64 start_time_nanos = 7; // SWAP // Value read from /proc/PID/status, field VmSwap. optional int64 swap_in_bytes = 8; // Deprecated: use ProcessMemorySnapshot atom instead. Always -1. optional int64 start_time_nanos = 10 [deprecated = true]; // Anonymous page size plus swap size. Values are read from /proc/PID/status. optional int32 anon_rss_and_swap_in_kilobytes = 9; // Deprecated: use ProcessMemorySnapshot atom instead. Always -1. optional int32 anon_rss_and_swap_in_kilobytes = 11 [deprecated = true]; } /* Loading cmds/statsd/src/external/StatsPullerManager.cpp +2 −7 Original line number Diff line number Diff line Loading @@ -145,16 +145,11 @@ std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { {.puller = new ResourceHealthManagerPuller(android::util::BATTERY_CYCLE_COUNT)}}, // process_memory_state {android::util::PROCESS_MEMORY_STATE, {.additiveFields = {4, 5, 6, 7, 8, 9}, {.additiveFields = {4, 5, 6, 7, 8}, .puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}}, // native_process_memory_state {android::util::NATIVE_PROCESS_MEMORY_STATE, {.additiveFields = {3, 4, 5, 6, 8}, .puller = new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}}, // process_memory_high_water_mark {android::util::PROCESS_MEMORY_HIGH_WATER_MARK, {.additiveFields = {3}, .puller = {.puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_HIGH_WATER_MARK)}}, // process_memory_snapshot {android::util::PROCESS_MEMORY_SNAPSHOT, Loading services/core/java/com/android/server/am/MemoryStatUtil.java +5 −62 Original line number Diff line number Diff line Loading @@ -39,8 +39,7 @@ import java.util.regex.Pattern; * Static utility methods related to {@link MemoryStat}. */ public final class MemoryStatUtil { static final int BYTES_IN_KILOBYTE = 1024; static final long JIFFY_NANOS = 1_000_000_000 / Os.sysconf(OsConstants._SC_CLK_TCK); static final int PAGE_SIZE = (int) Os.sysconf(OsConstants._SC_PAGESIZE); private static final String TAG = TAG_WITH_CLASS_NAME ? "MemoryStatUtil" : TAG_AM; Loading @@ -52,10 +51,6 @@ public final class MemoryStatUtil { private static final String MEMORY_STAT_FILE_FMT = "/dev/memcg/apps/uid_%d/pid_%d/memory.stat"; /** Path to procfs stat file for logging app start memory state */ private static final String PROC_STAT_FILE_FMT = "/proc/%d/stat"; /** Path to procfs status file for logging app memory state */ private static final String PROC_STATUS_FILE_FMT = "/proc/%d/status"; /** Path to procfs cmdline file. Used with pid: /proc/pid/cmdline. */ private static final String PROC_CMDLINE_FILE_FMT = "/proc/%d/cmdline"; private static final Pattern PGFAULT = Pattern.compile("total_pgfault (\\d+)"); private static final Pattern PGMAJFAULT = Pattern.compile("total_pgmajfault (\\d+)"); Loading @@ -63,16 +58,9 @@ public final class MemoryStatUtil { private static final Pattern CACHE_IN_BYTES = Pattern.compile("total_cache (\\d+)"); private static final Pattern SWAP_IN_BYTES = Pattern.compile("total_swap (\\d+)"); private static final Pattern PROCFS_RSS_IN_KILOBYTES = Pattern.compile("VmRSS:\\s*(\\d+)\\s*kB"); private static final Pattern PROCFS_ANON_RSS_IN_KILOBYTES = Pattern.compile("RssAnon:\\s*(\\d+)\\s*kB"); private static final Pattern PROCFS_SWAP_IN_KILOBYTES = Pattern.compile("VmSwap:\\s*(\\d+)\\s*kB"); private static final int PGFAULT_INDEX = 9; private static final int PGMAJFAULT_INDEX = 11; private static final int START_TIME_INDEX = 21; private static final int RSS_IN_PAGES_INDEX = 23; private MemoryStatUtil() {} Loading Loading @@ -106,19 +94,7 @@ public final class MemoryStatUtil { @Nullable public static MemoryStat readMemoryStatFromProcfs(int pid) { final String statPath = String.format(Locale.US, PROC_STAT_FILE_FMT, pid); final String statusPath = String.format(Locale.US, PROC_STATUS_FILE_FMT, pid); return parseMemoryStatFromProcfs(readFileContents(statPath), readFileContents(statusPath)); } /** * Reads cmdline of a process from procfs. * * Returns content of /proc/pid/cmdline (e.g. /system/bin/statsd) or an empty string * if the file is not available. */ public static String readCmdlineFromProcfs(int pid) { final String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid); return parseCmdlineFromProcfs(readFileContents(path)); return parseMemoryStatFromProcfs(readFileContents(statPath)); } private static String readFileContents(String path) { Loading Loading @@ -160,31 +136,19 @@ public final class MemoryStatUtil { */ @VisibleForTesting @Nullable static MemoryStat parseMemoryStatFromProcfs( String procStatContents, String procStatusContents) { static MemoryStat parseMemoryStatFromProcfs(String procStatContents) { if (procStatContents == null || procStatContents.isEmpty()) { return null; } if (procStatusContents == null || procStatusContents.isEmpty()) { return null; } final String[] splits = procStatContents.split(" "); if (splits.length < 24) { return null; } try { final MemoryStat memoryStat = new MemoryStat(); memoryStat.pgfault = Long.parseLong(splits[PGFAULT_INDEX]); memoryStat.pgmajfault = Long.parseLong(splits[PGMAJFAULT_INDEX]); memoryStat.rssInBytes = tryParseLong(PROCFS_RSS_IN_KILOBYTES, procStatusContents) * BYTES_IN_KILOBYTE; memoryStat.anonRssInBytes = tryParseLong(PROCFS_ANON_RSS_IN_KILOBYTES, procStatusContents) * BYTES_IN_KILOBYTE; memoryStat.swapInBytes = tryParseLong(PROCFS_SWAP_IN_KILOBYTES, procStatusContents) * BYTES_IN_KILOBYTE; memoryStat.startTimeNanos = Long.parseLong(splits[START_TIME_INDEX]) * JIFFY_NANOS; memoryStat.rssInBytes = Long.parseLong(splits[RSS_IN_PAGES_INDEX]) * PAGE_SIZE; return memoryStat; } catch (NumberFormatException e) { Slog.e(TAG, "Failed to parse value", e); Loading @@ -192,23 +156,6 @@ public final class MemoryStatUtil { } } /** * Parses cmdline out of the contents of the /proc/pid/cmdline file in procfs. * * Parsing is required to strip anything after first null byte. */ @VisibleForTesting static String parseCmdlineFromProcfs(String cmdline) { if (cmdline == null) { return ""; } int firstNullByte = cmdline.indexOf("\0"); if (firstNullByte == -1) { return cmdline; } return cmdline.substring(0, firstNullByte); } /** * Returns whether per-app memcg is available on device. */ Loading Loading @@ -237,13 +184,9 @@ public final class MemoryStatUtil { public long pgmajfault; /** For memcg stats, the anon rss + swap cache size. Otherwise total RSS. */ public long rssInBytes; /** Number of bytes of the anonymous RSS. Only present for non-memcg stats. */ public long anonRssInBytes; /** Number of bytes of page cache memory. Only present for memcg stats. */ public long cacheInBytes; /** Number of bytes of swap usage */ public long swapInBytes; /** Device time when the processes started. */ public long startTimeNanos; } } services/core/java/com/android/server/stats/ProcfsMemoryUtil.java +24 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,30 @@ final class ProcfsMemoryUtil { return null; } /** * Reads cmdline of a process from procfs. * * Returns content of /proc/pid/cmdline (e.g. /system/bin/statsd) or an empty string * if the file is not available. */ public static String readCmdlineFromProcfs(int pid) { return parseCmdline(readFile("/proc/" + pid + "/cmdline")); } /** * Parses cmdline out of the contents of the /proc/pid/cmdline file in procfs. * * Parsing is required to strip anything after the first null byte. */ @VisibleForTesting static String parseCmdline(String contents) { int firstNullByte = contents.indexOf("\0"); if (firstNullByte == -1) { return contents; } return contents.substring(0, firstNullByte); } private static String readFile(String path) { try { final File file = new File(path); Loading services/core/java/com/android/server/stats/StatsCompanionService.java +4 −44 Original line number Diff line number Diff line Loading @@ -24,11 +24,10 @@ import static android.os.storage.VolumeInfo.TYPE_PRIVATE; import static android.os.storage.VolumeInfo.TYPE_PUBLIC; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs; import static com.android.server.stats.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs; import static com.android.server.stats.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs; import static com.android.server.stats.ProcfsMemoryUtil.readCmdlineFromProcfs; import static com.android.server.stats.ProcfsMemoryUtil.readMemorySnapshotFromProcfs; import android.annotation.NonNull; Loading Loading @@ -1193,48 +1192,13 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { e.writeLong(memoryStat.rssInBytes); e.writeLong(memoryStat.cacheInBytes); e.writeLong(memoryStat.swapInBytes); e.writeLong(0); // unused e.writeLong(memoryStat.startTimeNanos); e.writeInt(anonAndSwapInKilobytes(memoryStat)); e.writeLong(-1); // unused e.writeLong(-1); // unused e.writeInt(-1); // unsed pulledData.add(e); } } private void pullNativeProcessMemoryState( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) { int[] pids = getPidsForCommands(MEMORY_INTERESTING_NATIVE_PROCESSES); for (int pid : pids) { String processName = readCmdlineFromProcfs(pid); MemoryStat memoryStat = readMemoryStatFromProcfs(pid); if (memoryStat == null) { continue; } int uid = getUidForPid(pid); // 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(uid)) { continue; } StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(uid); e.writeString(processName); e.writeLong(memoryStat.pgfault); e.writeLong(memoryStat.pgmajfault); e.writeLong(memoryStat.rssInBytes); e.writeLong(0); // unused e.writeLong(memoryStat.startTimeNanos); e.writeLong(memoryStat.swapInBytes); e.writeInt(anonAndSwapInKilobytes(memoryStat)); pulledData.add(e); } } private static int anonAndSwapInKilobytes(MemoryStat memoryStat) { return (int) ((memoryStat.anonRssInBytes + memoryStat.swapInBytes) / 1024); } private void pullProcessMemoryHighWaterMark( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) { Loading Loading @@ -2405,10 +2369,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { pullProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.NATIVE_PROCESS_MEMORY_STATE: { pullNativeProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.PROCESS_MEMORY_HIGH_WATER_MARK: { pullProcessMemoryHighWaterMark(tagId, elapsedNanos, wallClockNanos, ret); break; Loading Loading
cmds/statsd/src/atoms.proto +10 −48 Original line number Diff line number Diff line Loading @@ -378,7 +378,6 @@ message Atom { PowerProfile power_profile = 10033; ProcStatsPkgProc proc_stats_pkg_proc = 10034; ProcessCpuTime process_cpu_time = 10035; NativeProcessMemoryState native_process_memory_state = 10036; CpuTimePerThreadFreq cpu_time_per_thread_freq = 10037; OnDevicePowerMeasurement on_device_power_measurement = 10038; DeviceCalculatedPowerUse device_calculated_power_use = 10039; Loading Loading @@ -412,6 +411,8 @@ message Atom { // DO NOT USE field numbers above 100,000 in AOSP. // Field numbers 100,000 - 199,999 are reserved for non-AOSP (e.g. OEMs) to use. // Field numbers 200,000 and above are reserved for future use; do not use them at all. reserved 10036; } /** Loading Loading @@ -4019,8 +4020,8 @@ message ProcessMemoryState { optional int64 page_major_fault = 5; // RSS // Value is read from /proc/PID/status. Or from memory.stat, field // total_rss if per-app memory cgroups are enabled. // Value is read from memory.stat, field total_rss if per-app memory // cgroups are enabled. Otherwise, value from /proc/pid/stat. optional int64 rss_in_bytes = 6; // CACHE Loading @@ -4030,56 +4031,17 @@ message ProcessMemoryState { // SWAP // Value is read from memory.stat, field total_swap if per-app memory // cgroups are enabled. Otherwise, VmSwap from /proc/PID/status. // cgroups are enabled. Otherwise, 0. optional int64 swap_in_bytes = 8; // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always 0. // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always -1. optional int64 rss_high_watermark_in_bytes = 9 [deprecated = true]; // Elapsed real time when the process started. // Value is read from /proc/PID/stat, field 22. 0 if read from per-app memory cgroups. optional int64 start_time_nanos = 10; // Anonymous page size plus swap size. Values are read from /proc/PID/status. optional int32 anon_rss_and_swap_in_kilobytes = 11; } /* * Logs the memory stats for a native process (from procfs). * * Pulled from StatsCompanionService for selected native processes. */ message NativeProcessMemoryState { // The uid if available. -1 means not available. optional int32 uid = 1 [(is_uid) = true]; // The process name. // Value read from /proc/PID/cmdline. optional string process_name = 2; // # of page-faults optional int64 page_fault = 3; // # of major page-faults optional int64 page_major_fault = 4; // RSS // Value read from /proc/PID/status. optional int64 rss_in_bytes = 5; // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always 0. optional int64 rss_high_watermark_in_bytes = 6 [deprecated = true]; // Elapsed real time when the process started. // Value is read from /proc/PID/stat, field 22. optional int64 start_time_nanos = 7; // SWAP // Value read from /proc/PID/status, field VmSwap. optional int64 swap_in_bytes = 8; // Deprecated: use ProcessMemorySnapshot atom instead. Always -1. optional int64 start_time_nanos = 10 [deprecated = true]; // Anonymous page size plus swap size. Values are read from /proc/PID/status. optional int32 anon_rss_and_swap_in_kilobytes = 9; // Deprecated: use ProcessMemorySnapshot atom instead. Always -1. optional int32 anon_rss_and_swap_in_kilobytes = 11 [deprecated = true]; } /* Loading
cmds/statsd/src/external/StatsPullerManager.cpp +2 −7 Original line number Diff line number Diff line Loading @@ -145,16 +145,11 @@ std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { {.puller = new ResourceHealthManagerPuller(android::util::BATTERY_CYCLE_COUNT)}}, // process_memory_state {android::util::PROCESS_MEMORY_STATE, {.additiveFields = {4, 5, 6, 7, 8, 9}, {.additiveFields = {4, 5, 6, 7, 8}, .puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}}, // native_process_memory_state {android::util::NATIVE_PROCESS_MEMORY_STATE, {.additiveFields = {3, 4, 5, 6, 8}, .puller = new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}}, // process_memory_high_water_mark {android::util::PROCESS_MEMORY_HIGH_WATER_MARK, {.additiveFields = {3}, .puller = {.puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_HIGH_WATER_MARK)}}, // process_memory_snapshot {android::util::PROCESS_MEMORY_SNAPSHOT, Loading
services/core/java/com/android/server/am/MemoryStatUtil.java +5 −62 Original line number Diff line number Diff line Loading @@ -39,8 +39,7 @@ import java.util.regex.Pattern; * Static utility methods related to {@link MemoryStat}. */ public final class MemoryStatUtil { static final int BYTES_IN_KILOBYTE = 1024; static final long JIFFY_NANOS = 1_000_000_000 / Os.sysconf(OsConstants._SC_CLK_TCK); static final int PAGE_SIZE = (int) Os.sysconf(OsConstants._SC_PAGESIZE); private static final String TAG = TAG_WITH_CLASS_NAME ? "MemoryStatUtil" : TAG_AM; Loading @@ -52,10 +51,6 @@ public final class MemoryStatUtil { private static final String MEMORY_STAT_FILE_FMT = "/dev/memcg/apps/uid_%d/pid_%d/memory.stat"; /** Path to procfs stat file for logging app start memory state */ private static final String PROC_STAT_FILE_FMT = "/proc/%d/stat"; /** Path to procfs status file for logging app memory state */ private static final String PROC_STATUS_FILE_FMT = "/proc/%d/status"; /** Path to procfs cmdline file. Used with pid: /proc/pid/cmdline. */ private static final String PROC_CMDLINE_FILE_FMT = "/proc/%d/cmdline"; private static final Pattern PGFAULT = Pattern.compile("total_pgfault (\\d+)"); private static final Pattern PGMAJFAULT = Pattern.compile("total_pgmajfault (\\d+)"); Loading @@ -63,16 +58,9 @@ public final class MemoryStatUtil { private static final Pattern CACHE_IN_BYTES = Pattern.compile("total_cache (\\d+)"); private static final Pattern SWAP_IN_BYTES = Pattern.compile("total_swap (\\d+)"); private static final Pattern PROCFS_RSS_IN_KILOBYTES = Pattern.compile("VmRSS:\\s*(\\d+)\\s*kB"); private static final Pattern PROCFS_ANON_RSS_IN_KILOBYTES = Pattern.compile("RssAnon:\\s*(\\d+)\\s*kB"); private static final Pattern PROCFS_SWAP_IN_KILOBYTES = Pattern.compile("VmSwap:\\s*(\\d+)\\s*kB"); private static final int PGFAULT_INDEX = 9; private static final int PGMAJFAULT_INDEX = 11; private static final int START_TIME_INDEX = 21; private static final int RSS_IN_PAGES_INDEX = 23; private MemoryStatUtil() {} Loading Loading @@ -106,19 +94,7 @@ public final class MemoryStatUtil { @Nullable public static MemoryStat readMemoryStatFromProcfs(int pid) { final String statPath = String.format(Locale.US, PROC_STAT_FILE_FMT, pid); final String statusPath = String.format(Locale.US, PROC_STATUS_FILE_FMT, pid); return parseMemoryStatFromProcfs(readFileContents(statPath), readFileContents(statusPath)); } /** * Reads cmdline of a process from procfs. * * Returns content of /proc/pid/cmdline (e.g. /system/bin/statsd) or an empty string * if the file is not available. */ public static String readCmdlineFromProcfs(int pid) { final String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid); return parseCmdlineFromProcfs(readFileContents(path)); return parseMemoryStatFromProcfs(readFileContents(statPath)); } private static String readFileContents(String path) { Loading Loading @@ -160,31 +136,19 @@ public final class MemoryStatUtil { */ @VisibleForTesting @Nullable static MemoryStat parseMemoryStatFromProcfs( String procStatContents, String procStatusContents) { static MemoryStat parseMemoryStatFromProcfs(String procStatContents) { if (procStatContents == null || procStatContents.isEmpty()) { return null; } if (procStatusContents == null || procStatusContents.isEmpty()) { return null; } final String[] splits = procStatContents.split(" "); if (splits.length < 24) { return null; } try { final MemoryStat memoryStat = new MemoryStat(); memoryStat.pgfault = Long.parseLong(splits[PGFAULT_INDEX]); memoryStat.pgmajfault = Long.parseLong(splits[PGMAJFAULT_INDEX]); memoryStat.rssInBytes = tryParseLong(PROCFS_RSS_IN_KILOBYTES, procStatusContents) * BYTES_IN_KILOBYTE; memoryStat.anonRssInBytes = tryParseLong(PROCFS_ANON_RSS_IN_KILOBYTES, procStatusContents) * BYTES_IN_KILOBYTE; memoryStat.swapInBytes = tryParseLong(PROCFS_SWAP_IN_KILOBYTES, procStatusContents) * BYTES_IN_KILOBYTE; memoryStat.startTimeNanos = Long.parseLong(splits[START_TIME_INDEX]) * JIFFY_NANOS; memoryStat.rssInBytes = Long.parseLong(splits[RSS_IN_PAGES_INDEX]) * PAGE_SIZE; return memoryStat; } catch (NumberFormatException e) { Slog.e(TAG, "Failed to parse value", e); Loading @@ -192,23 +156,6 @@ public final class MemoryStatUtil { } } /** * Parses cmdline out of the contents of the /proc/pid/cmdline file in procfs. * * Parsing is required to strip anything after first null byte. */ @VisibleForTesting static String parseCmdlineFromProcfs(String cmdline) { if (cmdline == null) { return ""; } int firstNullByte = cmdline.indexOf("\0"); if (firstNullByte == -1) { return cmdline; } return cmdline.substring(0, firstNullByte); } /** * Returns whether per-app memcg is available on device. */ Loading Loading @@ -237,13 +184,9 @@ public final class MemoryStatUtil { public long pgmajfault; /** For memcg stats, the anon rss + swap cache size. Otherwise total RSS. */ public long rssInBytes; /** Number of bytes of the anonymous RSS. Only present for non-memcg stats. */ public long anonRssInBytes; /** Number of bytes of page cache memory. Only present for memcg stats. */ public long cacheInBytes; /** Number of bytes of swap usage */ public long swapInBytes; /** Device time when the processes started. */ public long startTimeNanos; } }
services/core/java/com/android/server/stats/ProcfsMemoryUtil.java +24 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,30 @@ final class ProcfsMemoryUtil { return null; } /** * Reads cmdline of a process from procfs. * * Returns content of /proc/pid/cmdline (e.g. /system/bin/statsd) or an empty string * if the file is not available. */ public static String readCmdlineFromProcfs(int pid) { return parseCmdline(readFile("/proc/" + pid + "/cmdline")); } /** * Parses cmdline out of the contents of the /proc/pid/cmdline file in procfs. * * Parsing is required to strip anything after the first null byte. */ @VisibleForTesting static String parseCmdline(String contents) { int firstNullByte = contents.indexOf("\0"); if (firstNullByte == -1) { return contents; } return contents.substring(0, firstNullByte); } private static String readFile(String path) { try { final File file = new File(path); Loading
services/core/java/com/android/server/stats/StatsCompanionService.java +4 −44 Original line number Diff line number Diff line Loading @@ -24,11 +24,10 @@ import static android.os.storage.VolumeInfo.TYPE_PRIVATE; import static android.os.storage.VolumeInfo.TYPE_PUBLIC; import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs; import static com.android.server.stats.IonMemoryUtil.readProcessSystemIonHeapSizesFromDebugfs; import static com.android.server.stats.IonMemoryUtil.readSystemIonHeapSizeFromDebugfs; import static com.android.server.stats.ProcfsMemoryUtil.readCmdlineFromProcfs; import static com.android.server.stats.ProcfsMemoryUtil.readMemorySnapshotFromProcfs; import android.annotation.NonNull; Loading Loading @@ -1193,48 +1192,13 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { e.writeLong(memoryStat.rssInBytes); e.writeLong(memoryStat.cacheInBytes); e.writeLong(memoryStat.swapInBytes); e.writeLong(0); // unused e.writeLong(memoryStat.startTimeNanos); e.writeInt(anonAndSwapInKilobytes(memoryStat)); e.writeLong(-1); // unused e.writeLong(-1); // unused e.writeInt(-1); // unsed pulledData.add(e); } } private void pullNativeProcessMemoryState( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) { int[] pids = getPidsForCommands(MEMORY_INTERESTING_NATIVE_PROCESSES); for (int pid : pids) { String processName = readCmdlineFromProcfs(pid); MemoryStat memoryStat = readMemoryStatFromProcfs(pid); if (memoryStat == null) { continue; } int uid = getUidForPid(pid); // 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(uid)) { continue; } StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); e.writeInt(uid); e.writeString(processName); e.writeLong(memoryStat.pgfault); e.writeLong(memoryStat.pgmajfault); e.writeLong(memoryStat.rssInBytes); e.writeLong(0); // unused e.writeLong(memoryStat.startTimeNanos); e.writeLong(memoryStat.swapInBytes); e.writeInt(anonAndSwapInKilobytes(memoryStat)); pulledData.add(e); } } private static int anonAndSwapInKilobytes(MemoryStat memoryStat) { return (int) ((memoryStat.anonRssInBytes + memoryStat.swapInBytes) / 1024); } private void pullProcessMemoryHighWaterMark( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) { Loading Loading @@ -2405,10 +2369,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { pullProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.NATIVE_PROCESS_MEMORY_STATE: { pullNativeProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret); break; } case StatsLog.PROCESS_MEMORY_HIGH_WATER_MARK: { pullProcessMemoryHighWaterMark(tagId, elapsedNanos, wallClockNanos, ret); break; Loading