Merge "Monitor swap" into qt-dev

This commit is contained in:
TreeHugger Robot
2019-04-19 08:53:22 +00:00
committed by Android (Google) Code Review
5 changed files with 43 additions and 20 deletions

View File

@@ -3804,7 +3804,7 @@ message ProcessMemoryState {
// SWAP // SWAP
// Value is read from memory.stat, field total_swap if per-app memory // Value is read from memory.stat, field total_swap if per-app memory
// cgroups are enabled. Otherwise, 0. // cgroups are enabled. Otherwise, VmSwap from /proc/PID/status.
optional int64 swap_in_bytes = 8; optional int64 swap_in_bytes = 8;
// Deprecated: use ProcessMemoryHighWaterMark atom instead. Always 0. // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always 0.
@@ -3844,6 +3844,10 @@ message NativeProcessMemoryState {
// Elapsed real time when the process started. // Elapsed real time when the process started.
// Value is read from /proc/PID/stat, field 22. // Value is read from /proc/PID/stat, field 22.
optional int64 start_time_nanos = 7; optional int64 start_time_nanos = 7;
// SWAP
// Value read from /proc/PID/status, field VmSwap.
optional int64 swap_in_bytes = 8;
} }
/* /*

View File

@@ -146,7 +146,7 @@ std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
.puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}}, .puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}},
// native_process_memory_state // native_process_memory_state
{android::util::NATIVE_PROCESS_MEMORY_STATE, {android::util::NATIVE_PROCESS_MEMORY_STATE,
{.additiveFields = {3, 4, 5, 6}, {.additiveFields = {3, 4, 5, 6, 8},
.puller = new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}}, .puller = new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}},
// process_memory_high_water_mark // process_memory_high_water_mark
{android::util::PROCESS_MEMORY_HIGH_WATER_MARK, {android::util::PROCESS_MEMORY_HIGH_WATER_MARK,

View File

@@ -40,7 +40,6 @@ import java.util.regex.Pattern;
*/ */
public final class MemoryStatUtil { public final class MemoryStatUtil {
static final int BYTES_IN_KILOBYTE = 1024; static final int BYTES_IN_KILOBYTE = 1024;
static final int PAGE_SIZE = 4096;
static final long JIFFY_NANOS = 1_000_000_000 / Os.sysconf(OsConstants._SC_CLK_TCK); static final long JIFFY_NANOS = 1_000_000_000 / Os.sysconf(OsConstants._SC_CLK_TCK);
private static final String TAG = TAG_WITH_CLASS_NAME ? "MemoryStatUtil" : TAG_AM; private static final String TAG = TAG_WITH_CLASS_NAME ? "MemoryStatUtil" : TAG_AM;
@@ -65,15 +64,20 @@ public final class MemoryStatUtil {
private static final Pattern RSS_IN_BYTES = Pattern.compile("total_rss (\\d+)"); private static final Pattern RSS_IN_BYTES = Pattern.compile("total_rss (\\d+)");
private static final Pattern CACHE_IN_BYTES = Pattern.compile("total_cache (\\d+)"); 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 SWAP_IN_BYTES = Pattern.compile("total_swap (\\d+)");
private static final Pattern RSS_HIGH_WATERMARK_IN_BYTES =
private static final Pattern RSS_HIGH_WATERMARK_IN_KILOBYTES =
Pattern.compile("VmHWM:\\s*(\\d+)\\s*kB"); Pattern.compile("VmHWM:\\s*(\\d+)\\s*kB");
private static final Pattern PROCFS_RSS_IN_KILOBYTES =
Pattern.compile("VmRSS:\\s*(\\d+)\\s*kB");
private static final Pattern PROCFS_SWAP_IN_KILOBYTES =
Pattern.compile("VmSwap:\\s*(\\d+)\\s*kB");
private static final Pattern ION_HEAP_SIZE_IN_BYTES = private static final Pattern ION_HEAP_SIZE_IN_BYTES =
Pattern.compile("\n\\s*total\\s*(\\d+)\\s*\n"); Pattern.compile("\n\\s*total\\s*(\\d+)\\s*\n");
private static final int PGFAULT_INDEX = 9; private static final int PGFAULT_INDEX = 9;
private static final int PGMAJFAULT_INDEX = 11; private static final int PGMAJFAULT_INDEX = 11;
private static final int START_TIME_INDEX = 21; private static final int START_TIME_INDEX = 21;
private static final int RSS_IN_PAGES_INDEX = 23;
private MemoryStatUtil() {} private MemoryStatUtil() {}
@@ -107,7 +111,8 @@ public final class MemoryStatUtil {
@Nullable @Nullable
public static MemoryStat readMemoryStatFromProcfs(int pid) { public static MemoryStat readMemoryStatFromProcfs(int pid) {
final String statPath = String.format(Locale.US, PROC_STAT_FILE_FMT, pid); final String statPath = String.format(Locale.US, PROC_STAT_FILE_FMT, pid);
return parseMemoryStatFromProcfs(readFileContents(statPath)); final String statusPath = String.format(Locale.US, PROC_STATUS_FILE_FMT, pid);
return parseMemoryStatFromProcfs(readFileContents(statPath), readFileContents(statusPath));
} }
/** /**
@@ -179,10 +184,14 @@ public final class MemoryStatUtil {
*/ */
@VisibleForTesting @VisibleForTesting
@Nullable @Nullable
static MemoryStat parseMemoryStatFromProcfs(String procStatContents) { static MemoryStat parseMemoryStatFromProcfs(
String procStatContents, String procStatusContents) {
if (procStatContents == null || procStatContents.isEmpty()) { if (procStatContents == null || procStatContents.isEmpty()) {
return null; return null;
} }
if (procStatusContents == null || procStatusContents.isEmpty()) {
return null;
}
final String[] splits = procStatContents.split(" "); final String[] splits = procStatContents.split(" ");
if (splits.length < 24) { if (splits.length < 24) {
@@ -193,7 +202,10 @@ public final class MemoryStatUtil {
final MemoryStat memoryStat = new MemoryStat(); final MemoryStat memoryStat = new MemoryStat();
memoryStat.pgfault = Long.parseLong(splits[PGFAULT_INDEX]); memoryStat.pgfault = Long.parseLong(splits[PGFAULT_INDEX]);
memoryStat.pgmajfault = Long.parseLong(splits[PGMAJFAULT_INDEX]); memoryStat.pgmajfault = Long.parseLong(splits[PGMAJFAULT_INDEX]);
memoryStat.rssInBytes = Long.parseLong(splits[RSS_IN_PAGES_INDEX]) * PAGE_SIZE; memoryStat.rssInBytes =
tryParseLong(PROCFS_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.startTimeNanos = Long.parseLong(splits[START_TIME_INDEX]) * JIFFY_NANOS;
return memoryStat; return memoryStat;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
@@ -212,7 +224,8 @@ public final class MemoryStatUtil {
return 0; return 0;
} }
// Convert value read from /proc/pid/status from kilobytes to bytes. // Convert value read from /proc/pid/status from kilobytes to bytes.
return tryParseLong(RSS_HIGH_WATERMARK_IN_BYTES, procStatusContents) * BYTES_IN_KILOBYTE; return tryParseLong(RSS_HIGH_WATERMARK_IN_KILOBYTES, procStatusContents)
* BYTES_IN_KILOBYTE;
} }

View File

@@ -1159,6 +1159,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
e.writeLong(memoryStat.rssInBytes); e.writeLong(memoryStat.rssInBytes);
e.writeLong(0); // unused e.writeLong(0); // unused
e.writeLong(memoryStat.startTimeNanos); e.writeLong(memoryStat.startTimeNanos);
e.writeLong(memoryStat.swapInBytes);
pulledData.add(e); pulledData.add(e);
} }
} }

View File

@@ -19,7 +19,6 @@ package com.android.server.am;
import static com.android.server.am.MemoryStatUtil.BYTES_IN_KILOBYTE; import static com.android.server.am.MemoryStatUtil.BYTES_IN_KILOBYTE;
import static com.android.server.am.MemoryStatUtil.JIFFY_NANOS; import static com.android.server.am.MemoryStatUtil.JIFFY_NANOS;
import static com.android.server.am.MemoryStatUtil.MemoryStat; import static com.android.server.am.MemoryStatUtil.MemoryStat;
import static com.android.server.am.MemoryStatUtil.PAGE_SIZE;
import static com.android.server.am.MemoryStatUtil.parseCmdlineFromProcfs; import static com.android.server.am.MemoryStatUtil.parseCmdlineFromProcfs;
import static com.android.server.am.MemoryStatUtil.parseIonHeapSizeFromDebugfs; import static com.android.server.am.MemoryStatUtil.parseIonHeapSizeFromDebugfs;
import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg;
@@ -102,7 +101,7 @@ public class MemoryStatUtilTest {
"0", "0",
"2222", // this in start time (in ticks per second) "2222", // this in start time (in ticks per second)
"1257177088", "1257177088",
"3", // this is RSS (number of pages) "3",
"4294967295", "4294967295",
"2936971264", "2936971264",
"2936991289", "2936991289",
@@ -147,8 +146,8 @@ public class MemoryStatUtilTest {
+ "VmSize:\t 4542636 kB\n" + "VmSize:\t 4542636 kB\n"
+ "VmLck:\t 0 kB\n" + "VmLck:\t 0 kB\n"
+ "VmPin:\t 0 kB\n" + "VmPin:\t 0 kB\n"
+ "VmHWM:\t 137668 kB\n" // RSS high watermark + "VmHWM:\t 137668 kB\n" // RSS high-water mark
+ "VmRSS:\t 126776 kB\n" + "VmRSS:\t 126776 kB\n" // RSS
+ "RssAnon:\t 37860 kB\n" + "RssAnon:\t 37860 kB\n"
+ "RssFile:\t 88764 kB\n" + "RssFile:\t 88764 kB\n"
+ "RssShmem:\t 152 kB\n" + "RssShmem:\t 152 kB\n"
@@ -158,7 +157,7 @@ public class MemoryStatUtilTest {
+ "VmLib:\t 102432 kB\n" + "VmLib:\t 102432 kB\n"
+ "VmPTE:\t 1300 kB\n" + "VmPTE:\t 1300 kB\n"
+ "VmPMD:\t 36 kB\n" + "VmPMD:\t 36 kB\n"
+ "VmSwap:\t 0 kB\n" + "VmSwap:\t 22 kB\n" // Swap
+ "Threads:\t95\n" + "Threads:\t95\n"
+ "SigQ:\t0/13641\n" + "SigQ:\t0/13641\n"
+ "SigPnd:\t0000000000000000\n" + "SigPnd:\t0000000000000000\n"
@@ -227,28 +226,34 @@ public class MemoryStatUtilTest {
@Test @Test
public void testParseMemoryStatFromProcfs_parsesCorrectValues() { public void testParseMemoryStatFromProcfs_parsesCorrectValues() {
MemoryStat stat = parseMemoryStatFromProcfs(PROC_STAT_CONTENTS); MemoryStat stat = parseMemoryStatFromProcfs(PROC_STAT_CONTENTS, PROC_STATUS_CONTENTS);
assertEquals(1, stat.pgfault); assertEquals(1, stat.pgfault);
assertEquals(2, stat.pgmajfault); assertEquals(2, stat.pgmajfault);
assertEquals(3 * PAGE_SIZE, stat.rssInBytes); assertEquals(126776 * BYTES_IN_KILOBYTE, stat.rssInBytes);
assertEquals(0, stat.cacheInBytes); assertEquals(0, stat.cacheInBytes);
assertEquals(0, stat.swapInBytes); assertEquals(22 * BYTES_IN_KILOBYTE, stat.swapInBytes);
assertEquals(2222 * JIFFY_NANOS, stat.startTimeNanos); assertEquals(2222 * JIFFY_NANOS, stat.startTimeNanos);
} }
@Test @Test
public void testParseMemoryStatFromProcfs_emptyContents() { public void testParseMemoryStatFromProcfs_emptyContents() {
MemoryStat stat = parseMemoryStatFromProcfs(""); MemoryStat stat = parseMemoryStatFromProcfs("", PROC_STATUS_CONTENTS);
assertNull(stat); assertNull(stat);
stat = parseMemoryStatFromProcfs(null); stat = parseMemoryStatFromProcfs(null, PROC_STATUS_CONTENTS);
assertNull(stat);
stat = parseMemoryStatFromProcfs(PROC_STAT_CONTENTS, "");
assertNull(stat);
stat = parseMemoryStatFromProcfs(PROC_STAT_CONTENTS, null);
assertNull(stat); assertNull(stat);
} }
@Test @Test
public void testParseMemoryStatFromProcfs_invalidValue() { public void testParseMemoryStatFromProcfs_invalidValue() {
String contents = String.join(" ", Collections.nCopies(24, "memory")); String contents = String.join(" ", Collections.nCopies(24, "memory"));
assertNull(parseMemoryStatFromProcfs(contents)); assertNull(parseMemoryStatFromProcfs(contents, PROC_STATUS_CONTENTS));
} }
@Test @Test