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

Commit 22b32308 authored by Eric Miao's avatar Eric Miao Committed by Android (Google) Code Review
Browse files

Merge "Report Post-GC memory metrics" into main

parents ce92352d ed7546f3
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -237,6 +237,7 @@ import com.android.internal.os.DebugStore;
import com.android.internal.os.RuntimeInit;
import com.android.internal.os.SafeZipPathValidatorCallback;
import com.android.internal.os.SomeArgs;
import com.android.internal.os.logging.MetricsLoggerWrapper;
import com.android.internal.policy.DecorView;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
@@ -7675,6 +7676,16 @@ public final class ActivityThread extends ClientTransactionHandler
                }
            }
        });

        // Register callback to report native memory metrics post GC cleanup
        if (Flags.reportPostgcMemoryMetrics() &&
            com.android.libcore.readonly.Flags.postCleanupApis()) {
            VMRuntime.addPostCleanupCallback(new Runnable() {
                @Override public void run() {
                    MetricsLoggerWrapper.logPostGcMemorySnapshot();
                }
            });
        }
    }

    @UnsupportedAppUsage
+10 −0
Original line number Diff line number Diff line
package: "android.app"
container: "system"

flag {
     namespace: "system_performance"
     name: "report_postgc_memory_metrics"
     is_exported: false
     description: "Controls whether to report memory metrics post GC cleanup"
     bug: "331243037"
}
+66 −8
Original line number Diff line number Diff line
@@ -13,9 +13,9 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.stats.pull;
package com.android.internal.os;

import static android.os.Process.PROC_OUT_STRING;
import static android.os.Process.*;

import android.annotation.Nullable;
import android.os.Process;
@@ -23,6 +23,7 @@ import android.util.SparseArray;

public final class ProcfsMemoryUtil {
    private static final int[] CMDLINE_OUT = new int[] { PROC_OUT_STRING };
    private static final int[] OOM_SCORE_ADJ_OUT = new int[] { PROC_NEWLINE_TERM | PROC_OUT_LONG };
    private static final String[] STATUS_KEYS = new String[] {
            "Uid:",
            "VmHWM:",
@@ -38,17 +39,34 @@ public final class ProcfsMemoryUtil {
    private ProcfsMemoryUtil() {}

    /**
     * Reads memory stats of a process from procfs. Returns values of the VmHWM, VmRss, AnonRSS,
     * VmSwap, RssShmem fields in /proc/pid/status in kilobytes or null if not available.
     * Reads memory stats of a process from procfs.
     *
     * Returns values of the VmHWM, VmRss, AnonRSS, VmSwap, RssShmem fields in
     * /proc/pid/status in kilobytes or null if not available.
     */
    @Nullable
    public static MemorySnapshot readMemorySnapshotFromProcfs(int pid) {
        return readMemorySnapshotFromProcfs("/proc/" + pid + "/status");
    }

    /**
     * Reads memory stats of the current process from procfs.
     *
     * Returns values of the VmHWM, VmRss, AnonRSS, VmSwap, RssShmem fields in
     * /proc/self/status in kilobytes or null if not available.
     */
    @Nullable
    public static MemorySnapshot readMemorySnapshotFromProcfs() {
        return readMemorySnapshotFromProcfs("/proc/self/status");
    }

    private static MemorySnapshot readMemorySnapshotFromProcfs(String path) {
        long[] output = new long[STATUS_KEYS.length];
        output[0] = -1;
        output[3] = -1;
        output[4] = -1;
        output[5] = -1;
        Process.readProcLines("/proc/" + pid + "/status", STATUS_KEYS, output);
        Process.readProcLines(path, STATUS_KEYS, output);
        if (output[0] == -1 || output[3] == -1 || output[4] == -1 || output[5] == -1) {
            // Could not open or parse file.
            return null;
@@ -70,13 +88,53 @@ public final class ProcfsMemoryUtil {
     * if the file is not available.
     */
    public static String readCmdlineFromProcfs(int pid) {
        return readCmdlineFromProcfs("/proc/" + pid + "/cmdline");
    }

    /**
     * Reads cmdline of the current process from procfs.
     *
     * Returns content of /proc/pid/cmdline (e.g. /system/bin/statsd) or an empty string
     * if the file is not available.
     */
    public static String readCmdlineFromProcfs() {
        return readCmdlineFromProcfs("/proc/self/cmdline");
    }

    private static String readCmdlineFromProcfs(String path) {
        String[] cmdline = new String[1];
        if (!Process.readProcFile("/proc/" + pid + "/cmdline", CMDLINE_OUT, cmdline, null, null)) {
        if (!Process.readProcFile(path, CMDLINE_OUT, cmdline, null, null)) {
            return "";
        }
        return cmdline[0];
    }

    /**
     * Reads oom_score_adj of a process from procfs
     *
     * Returns content of /proc/pid/oom_score_adj. Defaults to 0 if reading fails.
     */
    public static int readOomScoreAdjFromProcfs(int pid) {
        return readOomScoreAdjFromProcfs("/proc/" + pid + "/oom_score_adj");
    }

    /**
     * Reads oom_score_adj of the current process from procfs
     *
     * Returns content of /proc/pid/oom_score_adj. Defaults to 0 if reading fails.
     */
    public static int readOomScoreAdjFromProcfs() {
        return readOomScoreAdjFromProcfs("/proc/self/oom_score_adj");
    }

    private static int readOomScoreAdjFromProcfs(String path) {
        long[] oom_score_adj = new long[1];
        if (Process.readProcFile(path, OOM_SCORE_ADJ_OUT, null, oom_score_adj, null)) {
            return (int)oom_score_adj[0];
        }
        return 0;
    }

    /**
     * Scans all /proc/pid/cmdline entries and returns a mapping between pid and cmdline.
     */
@@ -109,7 +167,7 @@ public final class ProcfsMemoryUtil {

    /** Reads and parses selected entries of /proc/vmstat. */
    @Nullable
    static VmStat readVmStat() {
    public static VmStat readVmStat() {
        long[] vmstat = new long[VMSTAT_KEYS.length];
        vmstat[0] = -1;
        Process.readProcLines("/proc/vmstat", VMSTAT_KEYS, vmstat);
@@ -121,7 +179,7 @@ public final class ProcfsMemoryUtil {
        return result;
    }

    static final class VmStat {
    public static final class VmStat {
        public int oomKillCount;
    }
}
+48 −0
Original line number Diff line number Diff line
@@ -16,9 +16,15 @@

package com.android.internal.os.logging;

import android.app.Application;
import android.os.Process;
import android.util.Log;
import android.view.WindowManager.LayoutParams;

import com.android.internal.os.ProcfsMemoryUtil;
import com.android.internal.util.FrameworkStatsLog;
import java.util.Collection;
import libcore.util.NativeAllocationRegistry;

/**
 * Used to wrap different logging calls in one, so that client side code base is clean and more
@@ -49,4 +55,46 @@ public class MetricsLoggerWrapper {
            }
        }
    }

    public static void logPostGcMemorySnapshot() {
        if (!com.android.libcore.Flags.nativeMetrics()) {
            return;
        }
        int pid = Process.myPid();
        String processName = Application.getProcessName();
        Collection<NativeAllocationRegistry.Metrics> metrics =
            NativeAllocationRegistry.getMetrics();
        int nMetrics = metrics.size();

        String[] classNames = new String[nMetrics];
        long[] mallocedCount = new long[nMetrics];
        long[] mallocedBytes = new long[nMetrics];
        long[] nonmallocedCount = new long[nMetrics];
        long[] nonmallocedBytes = new long[nMetrics];

        int i = 0;
        for (NativeAllocationRegistry.Metrics m : metrics) {
            classNames[i] = m.getClassName();
            mallocedCount[i] = m.getMallocedCount();
            mallocedBytes[i] = m.getMallocedBytes();
            nonmallocedCount[i] = m.getNonmallocedCount();
            nonmallocedBytes[i] = m.getNonmallocedBytes();
            i++;
        }

        ProcfsMemoryUtil.MemorySnapshot m = ProcfsMemoryUtil.readMemorySnapshotFromProcfs();
        int oom_score_adj = ProcfsMemoryUtil.readOomScoreAdjFromProcfs();
        FrameworkStatsLog.write(FrameworkStatsLog.POSTGC_MEMORY_SNAPSHOT,
            m.uid, processName, pid,
            oom_score_adj,
            m.rssInKilobytes,
            m.anonRssInKilobytes,
            m.swapInKilobytes,
            m.anonRssInKilobytes + m.swapInKilobytes,
            classNames,
            mallocedCount,
            mallocedBytes,
            nonmallocedCount,
            nonmallocedBytes);
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
import static com.android.server.am.ActivityManagerService.MY_PID;
import static com.android.server.am.ProcessRecord.TAG;
import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
import static com.android.internal.os.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;

import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -58,7 +58,7 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.modules.expresslog.Counter;
import com.android.server.ResourcePressureUtil;
import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot;
import com.android.internal.os.ProcfsMemoryUtil.MemorySnapshot;
import com.android.server.wm.WindowProcessController;

import java.io.File;
Loading