diff options
| author | 2018-10-17 16:30:55 +0000 | |
|---|---|---|
| committer | 2018-10-17 16:30:55 +0000 | |
| commit | 7c5c113f531d859df71244d56514b855a886165a (patch) | |
| tree | 5d88123feca7a55ba82e6d19edaaca95e1e9d5cc | |
| parent | 03cc437b08441f67d5e1f3d18f224385b61a4afe (diff) | |
| parent | 0862158f13be9b6a940cc0b5940fe639edb89968 (diff) | |
Merge "Snapshot memory state for some native processes"
6 files changed, 116 insertions, 2 deletions
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 404599636aec..10b7c0b0117d 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -146,7 +146,7 @@ message Atom { } // Pulled events will start at field 10000. - // Next: 10025 + // Next: 10037 oneof pulled { WifiBytesTransfer wifi_bytes_transfer = 10000; WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001; @@ -184,6 +184,7 @@ message Atom { PowerProfile power_profile = 10033; ProcStats proc_stats_pkg_proc = 10034; ProcessCpuTime process_cpu_time = 10035; + NativeProcessMemoryState native_process_memory_state = 10036; } // DO NOT USE field numbers above 100,000 in AOSP. @@ -2345,6 +2346,31 @@ message ProcessMemoryState { } /* + * Logs the memory stats for a native process (from procfs). + */ +message NativeProcessMemoryState { + // The uid if available. -1 means not available. + optional int32 uid = 1 [(is_uid) = true]; + + // The process name. + optional string process_name = 2; + + // # of page-faults + optional int64 pgfault = 3; + + // # of major page-faults + optional int64 pgmajfault = 4; + + // RSS + optional int64 rss_in_bytes = 5; + + // RSS high watermark. + // Peak RSS usage of the process. Value is read from the VmHWM field in /proc/PID/status or + // from memory.max_usage_in_bytes under /dev/memcg if the device uses per-app memory cgroups. + optional int64 rss_high_watermark_in_bytes = 6; +} + +/* * Elapsed real time from SystemClock. */ message SystemElapsedRealtime { @@ -3022,4 +3048,4 @@ message ProcessCpuTime { optional int64 user_time_millis = 3; // Process cpu time in system space, cumulative from boot/process start optional int64 system_time_millis = 4; -}
\ No newline at end of file +} diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index 4c74c1701f3e..8871d4d054c5 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -170,6 +170,12 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { {2, 3}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}}, + // native_process_memory_state + {android::util::NATIVE_PROCESS_MEMORY_STATE, + {{3, 4, 5, 6}, + {2}, + 1 * NS_PER_SEC, + new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}}, // temperature {android::util::TEMPERATURE, {{}, {}, 1 * NS_PER_SEC, new ResourceThermalManagerPuller()}}, // binder_calls diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 296c063f5379..a7836af2c1e5 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -166,10 +166,19 @@ public abstract class ActivityManagerInternal { /** * Returns a list that contains the memory stats for currently running processes. + * + * Only processes managed by ActivityManagerService are included. */ public abstract List<ProcessMemoryState> getMemoryStateForProcesses(); /** + * Returns a list that contains the memory stats for monitored native processes. + * + * The list of the monitored processes is defined in MemoryStatUtil class. + */ + public abstract List<ProcessMemoryState> getMemoryStateForNativeProcesses(); + + /** * Checks to see if the calling pid is allowed to handle the user. Returns adjusted user id as * needed. */ diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index d5b618f954df..f9e61347503f 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -72,7 +72,9 @@ import static android.os.Process.THREAD_GROUP_TOP_APP; import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import static android.os.Process.THREAD_PRIORITY_FOREGROUND; import static android.os.Process.getFreeMemory; +import static android.os.Process.getPidsForCommands; import static android.os.Process.getTotalMemory; +import static android.os.Process.getUidForPid; import static android.os.Process.isThreadInProcess; import static android.os.Process.killProcess; import static android.os.Process.killProcessQuiet; @@ -138,8 +140,11 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSER import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; +import static com.android.server.am.MemoryStatUtil.MEMORY_STAT_INTERESTING_NATIVE_PROCESSES; import static com.android.server.am.MemoryStatUtil.hasMemcg; +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 android.Manifest; import android.Manifest.permission; @@ -20498,6 +20503,28 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override + public List<ProcessMemoryState> getMemoryStateForNativeProcesses() { + List<ProcessMemoryState> processMemoryStates = new ArrayList<>(); + int[] pids = getPidsForCommands(MEMORY_STAT_INTERESTING_NATIVE_PROCESSES); + for (int i = 0; i < pids.length; i++) { + int pid = pids[i]; + MemoryStat memoryStat = readMemoryStatFromProcfs(pid); + if (memoryStat == null) { + continue; + } + int uid = getUidForPid(pid); + String processName = readCmdlineFromProcfs(pid); + int oomScore = -1; // Unused, not included in the NativeProcessMemoryState atom. + ProcessMemoryState processMemoryState = new ProcessMemoryState(uid, processName, + oomScore, memoryStat.pgfault, memoryStat.pgmajfault, + memoryStat.rssInBytes, memoryStat.cacheInBytes, memoryStat.swapInBytes, + memoryStat.rssHighWatermarkInBytes); + processMemoryStates.add(processMemoryState); + } + return processMemoryStates; + } + + @Override public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, int allowMode, String name, String callerPackage) { return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll, diff --git a/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java index 98f3f95ebb87..23ae77d9a756 100644 --- a/services/core/java/com/android/server/am/MemoryStatUtil.java +++ b/services/core/java/com/android/server/am/MemoryStatUtil.java @@ -37,6 +37,17 @@ import java.util.regex.Pattern; * Static utility methods related to {@link MemoryStat}. */ final class MemoryStatUtil { + /** + * Which native processes to create {@link MemoryStat} for. + * + * <p>Processes are matched by their cmdline in procfs. Example: cat /proc/pid/cmdline returns + * /system/bin/statsd for the stats daemon. + */ + static final String[] MEMORY_STAT_INTERESTING_NATIVE_PROCESSES = new String[]{ + "/system/bin/statsd", // Stats daemon. + "/system/bin/surfaceflinger", + }; + static final int BYTES_IN_KILOBYTE = 1024; static final int PAGE_SIZE = 4096; @@ -57,6 +68,8 @@ final class MemoryStatUtil { 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+)"); @@ -119,6 +132,18 @@ final class MemoryStatUtil { return stat; } + /** + * 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. + */ + static String readCmdlineFromProcfs(int pid) { + String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid); + String cmdline = readFileContents(path); + return cmdline != null ? cmdline : ""; + } + private static String readFileContents(String path) { final File file = new File(path); if (!file.exists()) { diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index 14434cdcb4f7..6db7e4f1a800 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -1004,6 +1004,23 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } + private void pullNativeProcessMemoryState( + int tagId, long elapsedNanos, long wallClockNanos, + List<StatsLogEventWrapper> pulledData) { + List<ProcessMemoryState> processMemoryStates = LocalServices.getService( + ActivityManagerInternal.class).getMemoryStateForNativeProcesses(); + for (ProcessMemoryState processMemoryState : processMemoryStates) { + StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos); + e.writeInt(processMemoryState.uid); + e.writeString(processMemoryState.processName); + e.writeLong(processMemoryState.pgfault); + e.writeLong(processMemoryState.pgmajfault); + e.writeLong(processMemoryState.rssInBytes); + e.writeLong(processMemoryState.rssHighWatermarkInBytes); + pulledData.add(e); + } + } + private void pullBinderCallsStats( int tagId, long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) { @@ -1509,6 +1526,10 @@ 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.BINDER_CALLS: { pullBinderCallsStats(tagId, elapsedNanos, wallClockNanos, ret); break; |