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:
@@ -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;
|
||||
|
||||
14
cmds/statsd/src/external/StatsPullerManager.cpp
vendored
14
cmds/statsd/src/external/StatsPullerManager.cpp
vendored
@@ -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)}},
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user