Migrate ProcessMemory pullers

Test: atest UidAtomTests#testProcessMemoryState
Test: atest UidAtomTests#testProcessMemoryHighWaterMark
Test: atest UidAtomTests#testProcessMemorySnapshot
Test: adb shell cmd stats pull-source 10013
Test: adb shell cmd stats pull-source 10042
Test: adb shell cmd stats pull-source 10064
Change-Id: I0ce870a3fec668e380a6b6412f278033d6734f35
This commit is contained in:
Jeffrey Huang
2020-01-15 15:36:42 -08:00
parent 250e7aad89
commit b1c1634325
3 changed files with 189 additions and 164 deletions

View File

@@ -722,132 +722,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
pulledData.add(e);
}
private void pullProcessMemoryState(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
List<ProcessMemoryState> processMemoryStates =
LocalServices.getService(
ActivityManagerInternal.class).getMemoryStateForProcesses();
for (ProcessMemoryState processMemoryState : processMemoryStates) {
final MemoryStat memoryStat = readMemoryStatFromFilesystem(processMemoryState.uid,
processMemoryState.pid);
if (memoryStat == null) {
continue;
}
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
e.writeInt(processMemoryState.uid);
e.writeString(processMemoryState.processName);
e.writeInt(processMemoryState.oomScore);
e.writeLong(memoryStat.pgfault);
e.writeLong(memoryStat.pgmajfault);
e.writeLong(memoryStat.rssInBytes);
e.writeLong(memoryStat.cacheInBytes);
e.writeLong(memoryStat.swapInBytes);
e.writeLong(-1); // unused
e.writeLong(-1); // unused
e.writeInt(-1); // unsed
pulledData.add(e);
}
}
private void pullProcessMemoryHighWaterMark(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
List<ProcessMemoryState> managedProcessList =
LocalServices.getService(
ActivityManagerInternal.class).getMemoryStateForProcesses();
for (ProcessMemoryState managedProcess : managedProcessList) {
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
if (snapshot == null) {
continue;
}
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
e.writeInt(managedProcess.uid);
e.writeString(managedProcess.processName);
// RSS high-water mark in bytes.
e.writeLong((long) snapshot.rssHighWaterMarkInKilobytes * 1024L);
e.writeInt(snapshot.rssHighWaterMarkInKilobytes);
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;
}
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
e.writeInt(snapshot.uid);
e.writeString(cmdLine);
// RSS high-water mark in bytes.
e.writeLong((long) snapshot.rssHighWaterMarkInKilobytes * 1024L);
e.writeInt(snapshot.rssHighWaterMarkInKilobytes);
pulledData.add(e);
});
// Invoke rss_hwm_reset binary to reset RSS HWM counters for all processes.
SystemProperties.set("sys.rss_hwm_reset.on", "1");
}
private void pullProcessMemorySnapshot(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
List<ProcessMemoryState> managedProcessList =
LocalServices.getService(
ActivityManagerInternal.class).getMemoryStateForProcesses();
for (ProcessMemoryState managedProcess : managedProcessList) {
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
if (snapshot == null) {
continue;
}
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
e.writeInt(managedProcess.uid);
e.writeString(managedProcess.processName);
e.writeInt(managedProcess.pid);
e.writeInt(managedProcess.oomScore);
e.writeInt(snapshot.rssInKilobytes);
e.writeInt(snapshot.anonRssInKilobytes);
e.writeInt(snapshot.swapInKilobytes);
e.writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes);
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;
}
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
e.writeInt(snapshot.uid);
e.writeString(cmdLine);
e.writeInt(pid);
e.writeInt(-1001); // Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.
e.writeInt(snapshot.rssInKilobytes);
e.writeInt(snapshot.anonRssInKilobytes);
e.writeInt(snapshot.swapInKilobytes);
e.writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes);
pulledData.add(e);
});
}
private static boolean isAppUid(int uid) {
return uid >= MIN_APP_UID;
}
private void pullSystemIonHeapSize(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
@@ -1823,21 +1697,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
break;
}
case StatsLog.PROCESS_MEMORY_STATE: {
pullProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
case StatsLog.PROCESS_MEMORY_HIGH_WATER_MARK: {
pullProcessMemoryHighWaterMark(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
case StatsLog.PROCESS_MEMORY_SNAPSHOT: {
pullProcessMemorySnapshot(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
case StatsLog.SYSTEM_ION_HEAP_SIZE: {
pullSystemIonHeapSize(tagId, elapsedNanos, wallClockNanos, ret);
break;

View File

@@ -95,20 +95,6 @@ std::map<PullerKey, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
{{.atomTag = android::util::BATTERY_CYCLE_COUNT},
{.puller = new ResourceHealthManagerPuller(android::util::BATTERY_CYCLE_COUNT)}},
// process_memory_state
{{.atomTag = android::util::PROCESS_MEMORY_STATE},
{.additiveFields = {4, 5, 6, 7, 8},
.puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}},
// process_memory_high_water_mark
{{.atomTag = android::util::PROCESS_MEMORY_HIGH_WATER_MARK},
{.puller =
new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_HIGH_WATER_MARK)}},
// process_memory_snapshot
{{.atomTag = android::util::PROCESS_MEMORY_SNAPSHOT},
{.puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_SNAPSHOT)}},
// system_ion_heap_size
{{.atomTag = android::util::SYSTEM_ION_HEAP_SIZE},
{.puller = new StatsCompanionServicePuller(android::util::SYSTEM_ION_HEAP_SIZE)}},

View File

@@ -1004,27 +1004,207 @@ public class StatsPullAtomService extends SystemService {
}
private void registerProcessMemoryState() {
// No op.
int tagId = StatsLog.PROCESS_MEMORY_STATE;
PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
.setAdditiveFields(new int[] {4, 5, 6, 7, 8})
.build();
mStatsManager.registerPullAtomCallback(
tagId,
metadata,
(atomTag, data) -> pullProcessMemoryState(atomTag, data),
BackgroundThread.getExecutor()
);
}
private void pullProcessMemoryState() {
// No op.
private int pullProcessMemoryState(int atomTag, List<StatsEvent> pulledData) {
List<ProcessMemoryState> processMemoryStates =
LocalServices.getService(ActivityManagerInternal.class)
.getMemoryStateForProcesses();
for (ProcessMemoryState processMemoryState : processMemoryStates) {
final MemoryStat memoryStat = readMemoryStatFromFilesystem(processMemoryState.uid,
processMemoryState.pid);
if (memoryStat == null) {
continue;
}
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
.writeInt(processMemoryState.uid)
.writeString(processMemoryState.processName)
.writeInt(processMemoryState.oomScore)
.writeLong(memoryStat.pgfault)
.writeLong(memoryStat.pgmajfault)
.writeLong(memoryStat.rssInBytes)
.writeLong(memoryStat.cacheInBytes)
.writeLong(memoryStat.swapInBytes)
.writeLong(-1) // unused
.writeLong(-1) // unused
.writeInt(-1) // unused
.build();
pulledData.add(e);
}
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.
*
* <p>Used to quickly discard memory snapshots of the zygote forks from native process
* measurements.
*/
private static final int MIN_APP_UID = 10_000;
private static boolean isAppUid(int uid) {
return uid >= MIN_APP_UID;
}
private void registerProcessMemoryHighWaterMark() {
// No op.
int tagId = StatsLog.PROCESS_MEMORY_HIGH_WATER_MARK;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
(atomTag, data) -> pullProcessMemoryHighWaterMark(atomTag, data),
BackgroundThread.getExecutor()
);
}
private void pullProcessMemoryHighWaterMark() {
// No op.
private int pullProcessMemoryHighWaterMark(int atomTag, List<StatsEvent> pulledData) {
List<ProcessMemoryState> managedProcessList =
LocalServices.getService(ActivityManagerInternal.class)
.getMemoryStateForProcesses();
for (ProcessMemoryState managedProcess : managedProcessList) {
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
if (snapshot == null) {
continue;
}
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
.writeInt(managedProcess.uid)
.writeString(managedProcess.processName)
// RSS high-water mark in bytes.
.writeLong(snapshot.rssHighWaterMarkInKilobytes * 1024L)
.writeInt(snapshot.rssHighWaterMarkInKilobytes)
.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;
}
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
.writeInt(snapshot.uid)
.writeString(cmdLine)
// 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;
}
private void registerProcessMemorySnapshot() {
// No op.
int tagId = StatsLog.PROCESS_MEMORY_SNAPSHOT;
mStatsManager.registerPullAtomCallback(
tagId,
null, // use default PullAtomMetadata values
(atomTag, data) -> pullProcessMemorySnapshot(atomTag, data),
BackgroundThread.getExecutor()
);
}
private void pullProcessMemorySnapshot() {
// No op.
private int pullProcessMemorySnapshot(int atomTag, List<StatsEvent> pulledData) {
List<ProcessMemoryState> managedProcessList =
LocalServices.getService(ActivityManagerInternal.class)
.getMemoryStateForProcesses();
for (ProcessMemoryState managedProcess : managedProcessList) {
final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(managedProcess.pid);
if (snapshot == null) {
continue;
}
StatsEvent e = StatsEvent.newBuilder()
.writeInt(managedProcess.uid)
.writeString(managedProcess.processName)
.writeInt(managedProcess.pid)
.writeInt(managedProcess.oomScore)
.writeInt(snapshot.rssInKilobytes)
.writeInt(snapshot.anonRssInKilobytes)
.writeInt(snapshot.swapInKilobytes)
.writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
.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;
}
StatsEvent e = StatsEvent.newBuilder()
.setAtomId(atomTag)
.writeInt(snapshot.uid)
.writeString(cmdLine)
.writeInt(pid)
.writeInt(-1001) // Placeholder for native processes, OOM_SCORE_ADJ_MIN - 1.
.writeInt(snapshot.rssInKilobytes)
.writeInt(snapshot.anonRssInKilobytes)
.writeInt(snapshot.swapInKilobytes)
.writeInt(snapshot.anonRssInKilobytes + snapshot.swapInKilobytes)
.build();
pulledData.add(e);
});
return StatsManager.PULL_SUCCESS;
}
private void registerSystemIonHeapSize() {