Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79a58a7f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Monitor swap" into qt-dev

parents 3da53d52 44af3b32
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -3804,7 +3804,7 @@ message ProcessMemoryState {

    // SWAP
    // 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;

    // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always 0.
@@ -3844,6 +3844,10 @@ message NativeProcessMemoryState {
    // 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;
}

/*
+1 −1
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
          .puller = new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}},
        // 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)}},
        // process_memory_high_water_mark
        {android::util::PROCESS_MEMORY_HIGH_WATER_MARK,
+20 −7
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import java.util.regex.Pattern;
 */
public final class MemoryStatUtil {
    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);

    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 CACHE_IN_BYTES = Pattern.compile("total_cache (\\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");
    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 =
            Pattern.compile("\n\\s*total\\s*(\\d+)\\s*\n");

    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() {}

@@ -107,7 +111,8 @@ public final class MemoryStatUtil {
    @Nullable
    public static MemoryStat readMemoryStatFromProcfs(int 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
    @Nullable
    static MemoryStat parseMemoryStatFromProcfs(String procStatContents) {
    static MemoryStat parseMemoryStatFromProcfs(
            String procStatContents, String procStatusContents) {
        if (procStatContents == null || procStatContents.isEmpty()) {
            return null;
        }
        if (procStatusContents == null || procStatusContents.isEmpty()) {
            return null;
        }

        final String[] splits = procStatContents.split(" ");
        if (splits.length < 24) {
@@ -193,7 +202,10 @@ public final class MemoryStatUtil {
            final MemoryStat memoryStat = new MemoryStat();
            memoryStat.pgfault = Long.parseLong(splits[PGFAULT_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;
            return memoryStat;
        } catch (NumberFormatException e) {
@@ -212,7 +224,8 @@ public final class MemoryStatUtil {
            return 0;
        }
        // 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;
    }


+1 −0
Original line number Diff line number Diff line
@@ -1159,6 +1159,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
            e.writeLong(memoryStat.rssInBytes);
            e.writeLong(0);  // unused
            e.writeLong(memoryStat.startTimeNanos);
            e.writeLong(memoryStat.swapInBytes);
            pulledData.add(e);
        }
    }
+16 −11
Original line number Diff line number Diff line
@@ -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.JIFFY_NANOS;
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.parseIonHeapSizeFromDebugfs;
import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg;
@@ -102,7 +101,7 @@ public class MemoryStatUtilTest {
            "0",
            "2222", // this in start time (in ticks per second)
            "1257177088",
            "3", // this is RSS (number of pages)
            "3",
            "4294967295",
            "2936971264",
            "2936991289",
@@ -147,8 +146,8 @@ public class MemoryStatUtilTest {
            + "VmSize:\t 4542636 kB\n"
            + "VmLck:\t       0 kB\n"
            + "VmPin:\t       0 kB\n"
            + "VmHWM:\t  137668 kB\n" // RSS high watermark
            + "VmRSS:\t  126776 kB\n"
            + "VmHWM:\t  137668 kB\n" // RSS high-water mark
            + "VmRSS:\t  126776 kB\n" // RSS
            + "RssAnon:\t   37860 kB\n"
            + "RssFile:\t   88764 kB\n"
            + "RssShmem:\t     152 kB\n"
@@ -158,7 +157,7 @@ public class MemoryStatUtilTest {
            + "VmLib:\t  102432 kB\n"
            + "VmPTE:\t    1300 kB\n"
            + "VmPMD:\t      36 kB\n"
            + "VmSwap:\t       0 kB\n"
            + "VmSwap:\t      22 kB\n" // Swap
            + "Threads:\t95\n"
            + "SigQ:\t0/13641\n"
            + "SigPnd:\t0000000000000000\n"
@@ -227,28 +226,34 @@ public class MemoryStatUtilTest {

    @Test
    public void testParseMemoryStatFromProcfs_parsesCorrectValues() {
        MemoryStat stat = parseMemoryStatFromProcfs(PROC_STAT_CONTENTS);
        MemoryStat stat = parseMemoryStatFromProcfs(PROC_STAT_CONTENTS, PROC_STATUS_CONTENTS);
        assertEquals(1, stat.pgfault);
        assertEquals(2, stat.pgmajfault);
        assertEquals(3 * PAGE_SIZE, stat.rssInBytes);
        assertEquals(126776 * BYTES_IN_KILOBYTE, stat.rssInBytes);
        assertEquals(0, stat.cacheInBytes);
        assertEquals(0, stat.swapInBytes);
        assertEquals(22 * BYTES_IN_KILOBYTE, stat.swapInBytes);
        assertEquals(2222 * JIFFY_NANOS, stat.startTimeNanos);
    }

    @Test
    public void testParseMemoryStatFromProcfs_emptyContents() {
        MemoryStat stat = parseMemoryStatFromProcfs("");
        MemoryStat stat = parseMemoryStatFromProcfs("", PROC_STATUS_CONTENTS);
        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);
    }

    @Test
    public void testParseMemoryStatFromProcfs_invalidValue() {
        String contents = String.join(" ", Collections.nCopies(24, "memory"));
        assertNull(parseMemoryStatFromProcfs(contents));
        assertNull(parseMemoryStatFromProcfs(contents, PROC_STATUS_CONTENTS));
    }

    @Test