Loading services/core/java/com/android/server/am/ActivityManagerService.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -563,6 +563,8 @@ public class ActivityManagerService extends IActivityManager.Stub public final IntentFirewall mIntentFirewall; public final IntentFirewall mIntentFirewall; public OomAdjProfiler mOomAdjProfiler = new OomAdjProfiler(); // Whether we should use SCHED_FIFO for UI and RenderThreads. // Whether we should use SCHED_FIFO for UI and RenderThreads. private boolean mUseFifoUiScheduling = false; private boolean mUseFifoUiScheduling = false; Loading Loading @@ -2628,6 +2630,7 @@ public class ActivityManagerService extends IActivityManager.Stub mOnBattery = DEBUG_POWER ? true mOnBattery = DEBUG_POWER ? true : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); mBatteryStatsService.getActiveStatistics().setCallback(this); mBatteryStatsService.getActiveStatistics().setCallback(this); mOomAdjProfiler.batteryPowerChanged(mOnBattery); mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); Loading Loading @@ -2916,12 +2919,14 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized(mPidsSelfLocked) { synchronized(mPidsSelfLocked) { mOnBattery = DEBUG_POWER ? true : onBattery; mOnBattery = DEBUG_POWER ? true : onBattery; } } mOomAdjProfiler.batteryPowerChanged(onBattery); } } } } @Override @Override public void batteryStatsReset() { public void batteryStatsReset() { BinderCallsStatsService.reset(); BinderCallsStatsService.reset(); mOomAdjProfiler.reset(); } } @Override @Override Loading Loading @@ -10243,6 +10248,7 @@ public class ActivityManagerService extends IActivityManager.Stub mServices.updateScreenStateLocked(isAwake); mServices.updateScreenStateLocked(isAwake); reportCurWakefulnessUsageEventLocked(); reportCurWakefulnessUsageEventLocked(); mActivityTaskManager.onScreenAwakeChanged(isAwake); mActivityTaskManager.onScreenAwakeChanged(isAwake); mOomAdjProfiler.onWakefulnessChanged(wakefulness); } } updateOomAdjLocked(); updateOomAdjLocked(); } } Loading Loading @@ -12730,6 +12736,11 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println("-------------------------------------------------------------------------------"); pw.println("-------------------------------------------------------------------------------"); } } dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId); dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } mOomAdjProfiler.dump(pw); } } } } Binder.restoreCallingIdentity(origId); Binder.restoreCallingIdentity(origId); Loading Loading @@ -20677,6 +20688,7 @@ public class ActivityManagerService extends IActivityManager.Stub @GuardedBy("this") @GuardedBy("this") final void updateOomAdjLocked() { final void updateOomAdjLocked() { mOomAdjProfiler.oomAdjStarted(); final ActivityRecord TOP_ACT = resumedAppLocked(); final ActivityRecord TOP_ACT = resumedAppLocked(); final ProcessRecord TOP_APP = TOP_ACT != null && TOP_ACT.hasProcess() final ProcessRecord TOP_APP = TOP_ACT != null && TOP_ACT.hasProcess() ? (ProcessRecord) TOP_ACT.app.mOwner : null; ? (ProcessRecord) TOP_ACT.app.mOwner : null; Loading Loading @@ -21188,6 +21200,7 @@ public class ActivityManagerService extends IActivityManager.Stub Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms"); Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms"); } } } } mOomAdjProfiler.oomAdjEnded(); } } @Override @Override services/core/java/com/android/server/am/OomAdjProfiler.java 0 → 100644 +185 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.am; import android.os.PowerManagerInternal; import android.os.Process; import android.os.SystemClock; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BackgroundThread; import com.android.internal.os.ProcessCpuTracker; import com.android.internal.util.RingBuffer; import com.android.internal.util.function.pooled.PooledLambda; import java.io.PrintWriter; public class OomAdjProfiler { @GuardedBy("this") private boolean mOnBattery; @GuardedBy("this") private boolean mScreenOff; @GuardedBy("this") private long mOomAdjStartTimeMs; @GuardedBy("this") private boolean mOomAdjStarted; @GuardedBy("this") private CpuTimes mOomAdjRunTime = new CpuTimes(); @GuardedBy("this") private CpuTimes mSystemServerCpuTime = new CpuTimes(); @GuardedBy("this") private long mLastSystemServerCpuTimeMs; @GuardedBy("this") private boolean mSystemServerCpuTimeUpdateScheduled; private final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(false); @GuardedBy("this") final RingBuffer<CpuTimes> mOomAdjRunTimesHist = new RingBuffer<>(CpuTimes.class, 10); @GuardedBy("this") final RingBuffer<CpuTimes> mSystemServerCpuTimesHist = new RingBuffer<>(CpuTimes.class, 10); void batteryPowerChanged(boolean onBattery) { synchronized (this) { scheduleSystemServerCpuTimeUpdate(); mOnBattery = onBattery; } } void onWakefulnessChanged(int wakefulness) { synchronized (this) { scheduleSystemServerCpuTimeUpdate(); mScreenOff = wakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE; } } void oomAdjStarted() { synchronized (this) { mOomAdjStartTimeMs = SystemClock.currentThreadTimeMillis(); mOomAdjStarted = true; } } void oomAdjEnded() { synchronized (this) { if (!mOomAdjStarted) { return; } mOomAdjRunTime.addCpuTimeMs(SystemClock.currentThreadTimeMillis() - mOomAdjStartTimeMs); } } private void scheduleSystemServerCpuTimeUpdate() { synchronized (this) { if (mSystemServerCpuTimeUpdateScheduled) { return; } mSystemServerCpuTimeUpdateScheduled = true; BackgroundThread.getHandler().post(PooledLambda.obtainRunnable( OomAdjProfiler::updateSystemServerCpuTime, this, mOnBattery, mScreenOff).recycleOnUse()); } } private void updateSystemServerCpuTime(boolean onBattery, boolean screenOff) { final long cpuTimeMs = mProcessCpuTracker.getCpuTimeForPid(Process.myPid()); synchronized (this) { mSystemServerCpuTime.addCpuTimeMs( cpuTimeMs - mLastSystemServerCpuTimeMs, onBattery, screenOff); mLastSystemServerCpuTimeMs = cpuTimeMs; mSystemServerCpuTimeUpdateScheduled = false; notifyAll(); } } void reset() { synchronized (this) { if (mSystemServerCpuTime.isEmpty()) { return; } mOomAdjRunTimesHist.append(mOomAdjRunTime); mSystemServerCpuTimesHist.append(mSystemServerCpuTime); mOomAdjRunTime = new CpuTimes(); mSystemServerCpuTime = new CpuTimes(); } } void dump(PrintWriter pw) { synchronized (this) { if (mSystemServerCpuTimeUpdateScheduled) { while (mSystemServerCpuTimeUpdateScheduled) { try { wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } else { updateSystemServerCpuTime(mOnBattery, mScreenOff); } pw.println("System server and oomAdj runtimes (ms) in recent battery sessions " + "(most recent first):"); if (!mSystemServerCpuTime.isEmpty()) { pw.print(" "); pw.print("system_server="); pw.print(mSystemServerCpuTime); pw.print(" "); pw.print("oom_adj="); pw.println(mOomAdjRunTime); } final CpuTimes[] systemServerCpuTimes = mSystemServerCpuTimesHist.toArray(); final CpuTimes[] oomAdjRunTimes = mOomAdjRunTimesHist.toArray(); for (int i = oomAdjRunTimes.length - 1; i >= 0; --i) { pw.print(" "); pw.print("system_server="); pw.print(systemServerCpuTimes[i]); pw.print(" "); pw.print("oom_adj="); pw.println(oomAdjRunTimes[i]); } } } private class CpuTimes { private long mOnBatteryTimeMs; private long mOnBatteryScreenOffTimeMs; public void addCpuTimeMs(long cpuTimeMs) { addCpuTimeMs(cpuTimeMs, mOnBattery, mScreenOff); } public void addCpuTimeMs(long cpuTimeMs, boolean onBattery, boolean screenOff) { if (onBattery) { mOnBatteryTimeMs += cpuTimeMs; if (screenOff) { mOnBatteryScreenOffTimeMs += cpuTimeMs; } } } public boolean isEmpty() { return mOnBatteryTimeMs == 0 && mOnBatteryScreenOffTimeMs == 0; } public String toString() { return "[" + mOnBatteryTimeMs + "," + mOnBatteryScreenOffTimeMs + "]"; } } } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -563,6 +563,8 @@ public class ActivityManagerService extends IActivityManager.Stub public final IntentFirewall mIntentFirewall; public final IntentFirewall mIntentFirewall; public OomAdjProfiler mOomAdjProfiler = new OomAdjProfiler(); // Whether we should use SCHED_FIFO for UI and RenderThreads. // Whether we should use SCHED_FIFO for UI and RenderThreads. private boolean mUseFifoUiScheduling = false; private boolean mUseFifoUiScheduling = false; Loading Loading @@ -2628,6 +2630,7 @@ public class ActivityManagerService extends IActivityManager.Stub mOnBattery = DEBUG_POWER ? true mOnBattery = DEBUG_POWER ? true : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); mBatteryStatsService.getActiveStatistics().setCallback(this); mBatteryStatsService.getActiveStatistics().setCallback(this); mOomAdjProfiler.batteryPowerChanged(mOnBattery); mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); Loading Loading @@ -2916,12 +2919,14 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized(mPidsSelfLocked) { synchronized(mPidsSelfLocked) { mOnBattery = DEBUG_POWER ? true : onBattery; mOnBattery = DEBUG_POWER ? true : onBattery; } } mOomAdjProfiler.batteryPowerChanged(onBattery); } } } } @Override @Override public void batteryStatsReset() { public void batteryStatsReset() { BinderCallsStatsService.reset(); BinderCallsStatsService.reset(); mOomAdjProfiler.reset(); } } @Override @Override Loading Loading @@ -10243,6 +10248,7 @@ public class ActivityManagerService extends IActivityManager.Stub mServices.updateScreenStateLocked(isAwake); mServices.updateScreenStateLocked(isAwake); reportCurWakefulnessUsageEventLocked(); reportCurWakefulnessUsageEventLocked(); mActivityTaskManager.onScreenAwakeChanged(isAwake); mActivityTaskManager.onScreenAwakeChanged(isAwake); mOomAdjProfiler.onWakefulnessChanged(wakefulness); } } updateOomAdjLocked(); updateOomAdjLocked(); } } Loading Loading @@ -12730,6 +12736,11 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println("-------------------------------------------------------------------------------"); pw.println("-------------------------------------------------------------------------------"); } } dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId); dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage, dumpAppId); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } mOomAdjProfiler.dump(pw); } } } } Binder.restoreCallingIdentity(origId); Binder.restoreCallingIdentity(origId); Loading Loading @@ -20677,6 +20688,7 @@ public class ActivityManagerService extends IActivityManager.Stub @GuardedBy("this") @GuardedBy("this") final void updateOomAdjLocked() { final void updateOomAdjLocked() { mOomAdjProfiler.oomAdjStarted(); final ActivityRecord TOP_ACT = resumedAppLocked(); final ActivityRecord TOP_ACT = resumedAppLocked(); final ProcessRecord TOP_APP = TOP_ACT != null && TOP_ACT.hasProcess() final ProcessRecord TOP_APP = TOP_ACT != null && TOP_ACT.hasProcess() ? (ProcessRecord) TOP_ACT.app.mOwner : null; ? (ProcessRecord) TOP_ACT.app.mOwner : null; Loading Loading @@ -21188,6 +21200,7 @@ public class ActivityManagerService extends IActivityManager.Stub Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms"); Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms"); } } } } mOomAdjProfiler.oomAdjEnded(); } } @Override @Override
services/core/java/com/android/server/am/OomAdjProfiler.java 0 → 100644 +185 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2018 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.am; import android.os.PowerManagerInternal; import android.os.Process; import android.os.SystemClock; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BackgroundThread; import com.android.internal.os.ProcessCpuTracker; import com.android.internal.util.RingBuffer; import com.android.internal.util.function.pooled.PooledLambda; import java.io.PrintWriter; public class OomAdjProfiler { @GuardedBy("this") private boolean mOnBattery; @GuardedBy("this") private boolean mScreenOff; @GuardedBy("this") private long mOomAdjStartTimeMs; @GuardedBy("this") private boolean mOomAdjStarted; @GuardedBy("this") private CpuTimes mOomAdjRunTime = new CpuTimes(); @GuardedBy("this") private CpuTimes mSystemServerCpuTime = new CpuTimes(); @GuardedBy("this") private long mLastSystemServerCpuTimeMs; @GuardedBy("this") private boolean mSystemServerCpuTimeUpdateScheduled; private final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(false); @GuardedBy("this") final RingBuffer<CpuTimes> mOomAdjRunTimesHist = new RingBuffer<>(CpuTimes.class, 10); @GuardedBy("this") final RingBuffer<CpuTimes> mSystemServerCpuTimesHist = new RingBuffer<>(CpuTimes.class, 10); void batteryPowerChanged(boolean onBattery) { synchronized (this) { scheduleSystemServerCpuTimeUpdate(); mOnBattery = onBattery; } } void onWakefulnessChanged(int wakefulness) { synchronized (this) { scheduleSystemServerCpuTimeUpdate(); mScreenOff = wakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE; } } void oomAdjStarted() { synchronized (this) { mOomAdjStartTimeMs = SystemClock.currentThreadTimeMillis(); mOomAdjStarted = true; } } void oomAdjEnded() { synchronized (this) { if (!mOomAdjStarted) { return; } mOomAdjRunTime.addCpuTimeMs(SystemClock.currentThreadTimeMillis() - mOomAdjStartTimeMs); } } private void scheduleSystemServerCpuTimeUpdate() { synchronized (this) { if (mSystemServerCpuTimeUpdateScheduled) { return; } mSystemServerCpuTimeUpdateScheduled = true; BackgroundThread.getHandler().post(PooledLambda.obtainRunnable( OomAdjProfiler::updateSystemServerCpuTime, this, mOnBattery, mScreenOff).recycleOnUse()); } } private void updateSystemServerCpuTime(boolean onBattery, boolean screenOff) { final long cpuTimeMs = mProcessCpuTracker.getCpuTimeForPid(Process.myPid()); synchronized (this) { mSystemServerCpuTime.addCpuTimeMs( cpuTimeMs - mLastSystemServerCpuTimeMs, onBattery, screenOff); mLastSystemServerCpuTimeMs = cpuTimeMs; mSystemServerCpuTimeUpdateScheduled = false; notifyAll(); } } void reset() { synchronized (this) { if (mSystemServerCpuTime.isEmpty()) { return; } mOomAdjRunTimesHist.append(mOomAdjRunTime); mSystemServerCpuTimesHist.append(mSystemServerCpuTime); mOomAdjRunTime = new CpuTimes(); mSystemServerCpuTime = new CpuTimes(); } } void dump(PrintWriter pw) { synchronized (this) { if (mSystemServerCpuTimeUpdateScheduled) { while (mSystemServerCpuTimeUpdateScheduled) { try { wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } else { updateSystemServerCpuTime(mOnBattery, mScreenOff); } pw.println("System server and oomAdj runtimes (ms) in recent battery sessions " + "(most recent first):"); if (!mSystemServerCpuTime.isEmpty()) { pw.print(" "); pw.print("system_server="); pw.print(mSystemServerCpuTime); pw.print(" "); pw.print("oom_adj="); pw.println(mOomAdjRunTime); } final CpuTimes[] systemServerCpuTimes = mSystemServerCpuTimesHist.toArray(); final CpuTimes[] oomAdjRunTimes = mOomAdjRunTimesHist.toArray(); for (int i = oomAdjRunTimes.length - 1; i >= 0; --i) { pw.print(" "); pw.print("system_server="); pw.print(systemServerCpuTimes[i]); pw.print(" "); pw.print("oom_adj="); pw.println(oomAdjRunTimes[i]); } } } private class CpuTimes { private long mOnBatteryTimeMs; private long mOnBatteryScreenOffTimeMs; public void addCpuTimeMs(long cpuTimeMs) { addCpuTimeMs(cpuTimeMs, mOnBattery, mScreenOff); } public void addCpuTimeMs(long cpuTimeMs, boolean onBattery, boolean screenOff) { if (onBattery) { mOnBatteryTimeMs += cpuTimeMs; if (screenOff) { mOnBatteryScreenOffTimeMs += cpuTimeMs; } } } public boolean isEmpty() { return mOnBatteryTimeMs == 0 && mOnBatteryScreenOffTimeMs == 0; } public String toString() { return "[" + mOnBatteryTimeMs + "," + mOnBatteryScreenOffTimeMs + "]"; } } }