diff --git a/services/core/java/com/android/server/MemoryPressureUtil.java b/services/core/java/com/android/server/MemoryPressureUtil.java new file mode 100644 index 0000000000000..c34dc2f5a9b17 --- /dev/null +++ b/services/core/java/com/android/server/MemoryPressureUtil.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.os.StrictMode; +import android.util.Slog; + +import libcore.io.IoUtils; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; + +/** + * Utility method for memory pressure (PSI). + */ +public final class MemoryPressureUtil { + private static final String FILE = "/proc/pressure/memory"; + private static final String TAG = "MemoryPressure"; + + /** + * @return a stanza about memory PSI to add to a report. + */ + public static String currentPsiState() { + final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads(); + StringWriter contents = new StringWriter(); + try { + if (new File(FILE).exists()) { + contents.append("----- Output from /proc/pressure/memory -----\n"); + contents.append(IoUtils.readFileAsString(FILE)); + contents.append("----- End output from /proc/pressure/memory -----\n\n"); + } + } catch (IOException e) { + Slog.e(TAG, "Could not read " + FILE, e); + } finally { + StrictMode.setThreadPolicy(savedPolicy); + } + return contents.toString(); + } + + private MemoryPressureUtil(){} +} diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index 7797829c3f2fa..ac7867f29a793 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -610,6 +610,8 @@ public class Watchdog extends Thread { if (mPhonePid > 0) pids.add(mPhonePid); long anrTime = SystemClock.uptimeMillis(); + StringBuilder report = new StringBuilder(); + report.append(MemoryPressureUtil.currentPsiState()); ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(false); StringWriter tracesFileException = new StringWriter(); final File stack = ActivityManagerService.dumpStackTraces( @@ -621,7 +623,6 @@ public class Watchdog extends Thread { SystemClock.sleep(5000); processCpuTracker.update(); - StringBuilder report = new StringBuilder(); report.append(processCpuTracker.printCurrentState(anrTime)); report.append(tracesFileException.getBuffer()); diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 86df794e88f8b..c2f03ec8d6c41 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -66,6 +66,7 @@ import com.android.internal.os.BatteryStatsImpl; import com.android.internal.os.ProcessCpuTracker; import com.android.internal.os.Zygote; import com.android.internal.util.FrameworkStatsLog; +import com.android.server.MemoryPressureUtil; import com.android.server.wm.WindowProcessController; import com.android.server.wm.WindowProcessListener; @@ -1582,6 +1583,8 @@ class ProcessRecord implements WindowProcessListener { info.append("Parent: ").append(parentShortComponentName).append("\n"); } + StringBuilder report = new StringBuilder(); + report.append(MemoryPressureUtil.currentPsiState()); ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); // don't dump native PIDs for background ANRs unless it is the process of interest @@ -1614,7 +1617,6 @@ class ProcessRecord implements WindowProcessListener { (isSilentAnr()) ? null : processCpuTracker, (isSilentAnr()) ? null : lastPids, nativePids, tracesFileException); - StringBuilder report = new StringBuilder(); if (isMonitorCpuUsage()) { mService.updateCpuStatsNow(); synchronized (mService.mProcessCpuTracker) {