Merge "More work on procstats: save/restore state, fixes."
This commit is contained in:
committed by
Android (Google) Code Review
commit
f406e23012
@@ -244,7 +244,7 @@ public final class ActiveServices {
|
||||
r.lastActivity = SystemClock.uptimeMillis();
|
||||
r.startRequested = true;
|
||||
if (r.tracker != null) {
|
||||
r.tracker.setStarted(true, mAm.mProcessTracker.getMemFactor(), r.lastActivity);
|
||||
r.tracker.setStarted(true, mAm.mProcessTracker.getMemFactorLocked(), r.lastActivity);
|
||||
}
|
||||
r.callStart = false;
|
||||
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
|
||||
@@ -265,7 +265,7 @@ public final class ActiveServices {
|
||||
}
|
||||
service.startRequested = false;
|
||||
if (service.tracker != null) {
|
||||
service.tracker.setStarted(false, mAm.mProcessTracker.getMemFactor(),
|
||||
service.tracker.setStarted(false, mAm.mProcessTracker.getMemFactorLocked(),
|
||||
SystemClock.uptimeMillis());
|
||||
}
|
||||
service.callStart = false;
|
||||
@@ -365,7 +365,7 @@ public final class ActiveServices {
|
||||
}
|
||||
r.startRequested = false;
|
||||
if (r.tracker != null) {
|
||||
r.tracker.setStarted(false, mAm.mProcessTracker.getMemFactor(),
|
||||
r.tracker.setStarted(false, mAm.mProcessTracker.getMemFactorLocked(),
|
||||
SystemClock.uptimeMillis());
|
||||
}
|
||||
r.callStart = false;
|
||||
@@ -505,7 +505,7 @@ public final class ActiveServices {
|
||||
if (!s.hasAutoCreateConnections()) {
|
||||
// This is the first binding, let the tracker know.
|
||||
if (s.tracker != null) {
|
||||
s.tracker.setBound(true, mAm.mProcessTracker.getMemFactor(),
|
||||
s.tracker.setBound(true, mAm.mProcessTracker.getMemFactorLocked(),
|
||||
s.lastActivity);
|
||||
}
|
||||
}
|
||||
@@ -827,7 +827,7 @@ public final class ActiveServices {
|
||||
long now = SystemClock.uptimeMillis();
|
||||
if (r.executeNesting == 0) {
|
||||
if (r.tracker != null) {
|
||||
r.tracker.setExecuting(true, mAm.mProcessTracker.getMemFactor(), now);
|
||||
r.tracker.setExecuting(true, mAm.mProcessTracker.getMemFactorLocked(), now);
|
||||
}
|
||||
if (r.app != null) {
|
||||
if (r.app.executingServices.size() == 0) {
|
||||
@@ -1327,7 +1327,7 @@ public final class ActiveServices {
|
||||
((ServiceRestarter)r.restarter).setService(null);
|
||||
}
|
||||
|
||||
int memFactor = mAm.mProcessTracker.getMemFactor();
|
||||
int memFactor = mAm.mProcessTracker.getMemFactorLocked();
|
||||
long now = SystemClock.uptimeMillis();
|
||||
if (r.tracker != null) {
|
||||
r.tracker.setStarted(false, memFactor, now);
|
||||
@@ -1394,7 +1394,7 @@ public final class ActiveServices {
|
||||
boolean hasAutoCreate = s.hasAutoCreateConnections();
|
||||
if (!hasAutoCreate) {
|
||||
if (s.tracker != null) {
|
||||
s.tracker.setBound(false, mAm.mProcessTracker.getMemFactor(),
|
||||
s.tracker.setBound(false, mAm.mProcessTracker.getMemFactorLocked(),
|
||||
SystemClock.uptimeMillis());
|
||||
}
|
||||
}
|
||||
@@ -1490,7 +1490,7 @@ public final class ActiveServices {
|
||||
mAm.updateOomAdjLocked(r.app);
|
||||
}
|
||||
if (r.tracker != null) {
|
||||
r.tracker.setExecuting(false, mAm.mProcessTracker.getMemFactor(),
|
||||
r.tracker.setExecuting(false, mAm.mProcessTracker.getMemFactorLocked(),
|
||||
SystemClock.uptimeMillis());
|
||||
}
|
||||
}
|
||||
@@ -1685,7 +1685,7 @@ public final class ActiveServices {
|
||||
sr.isolatedProc = null;
|
||||
sr.executeNesting = 0;
|
||||
if (sr.tracker != null) {
|
||||
sr.tracker.setExecuting(false, mAm.mProcessTracker.getMemFactor(),
|
||||
sr.tracker.setExecuting(false, mAm.mProcessTracker.getMemFactorLocked(),
|
||||
SystemClock.uptimeMillis());
|
||||
}
|
||||
if (mStoppingServices.remove(sr)) {
|
||||
@@ -1720,7 +1720,7 @@ public final class ActiveServices {
|
||||
if (sr.pendingStarts.size() == 0) {
|
||||
sr.startRequested = false;
|
||||
if (sr.tracker != null) {
|
||||
sr.tracker.setStarted(false, mAm.mProcessTracker.getMemFactor(),
|
||||
sr.tracker.setStarted(false, mAm.mProcessTracker.getMemFactorLocked(),
|
||||
SystemClock.uptimeMillis());
|
||||
}
|
||||
if (!sr.hasAutoCreateConnections()) {
|
||||
|
||||
@@ -272,7 +272,11 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
|
||||
// The amount of time we will sample PSS of the current top process while the
|
||||
// screen is on.
|
||||
static final int PSS_TOP_INTERVAL = 5*60*1000;
|
||||
static final int PSS_TOP_INTERVAL = 2*60*1000;
|
||||
|
||||
// The amount of time we will sample PSS of any processes that more at least as
|
||||
// important as perceptible while the screen is on.
|
||||
static final int PSS_PERCEPTIBLE_INTERVAL = 10*60*1000;
|
||||
|
||||
// The maximum amount of time for a process to be around until we will take
|
||||
// a PSS snapshot on its next oom change.
|
||||
@@ -423,7 +427,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
* Tracking long-term execution of processes to look for abuse and other
|
||||
* bad app behavior.
|
||||
*/
|
||||
ProcessTracker mProcessTracker;
|
||||
final ProcessTracker mProcessTracker;
|
||||
|
||||
/**
|
||||
* The currently running isolated processes.
|
||||
@@ -1528,12 +1532,12 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
if (proc.thread != null) {
|
||||
oomAdj = proc.setAdj;
|
||||
pid = proc.pid;
|
||||
i++;
|
||||
} else {
|
||||
proc = null;
|
||||
oomAdj = 0;
|
||||
pid = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (proc != null) {
|
||||
long pss = Debug.getPss(pid);
|
||||
@@ -1620,7 +1624,6 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
m.mContext = context;
|
||||
m.mFactoryTest = factoryTest;
|
||||
m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
|
||||
m.mProcessTracker = new ProcessTracker(context);
|
||||
|
||||
m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);
|
||||
|
||||
@@ -1817,8 +1820,10 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
: mBatteryStatsService.getActiveStatistics().getIsOnBattery();
|
||||
mBatteryStatsService.getActiveStatistics().setCallback(this);
|
||||
|
||||
mUsageStatsService = new UsageStatsService(new File(
|
||||
systemDir, "usagestats").toString());
|
||||
mProcessTracker = new ProcessTracker(new File(systemDir, "procstats"));
|
||||
mProcessTracker.readLocked();
|
||||
|
||||
mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
|
||||
mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
|
||||
|
||||
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
|
||||
@@ -7636,6 +7641,9 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
mAppOpsService.shutdown();
|
||||
mUsageStatsService.shutdown();
|
||||
mBatteryStatsService.shutdown();
|
||||
synchronized (this) {
|
||||
mProcessTracker.shutdownLocked();
|
||||
}
|
||||
|
||||
return timedout;
|
||||
}
|
||||
@@ -14203,8 +14211,17 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
app.setRawAdj = app.curRawAdj;
|
||||
}
|
||||
|
||||
if (app == TOP_APP && now > (app.lastPssTime+PSS_TOP_INTERVAL)) {
|
||||
requestPssLocked(app, now, true);
|
||||
if (!mSleeping) {
|
||||
if (app == TOP_APP && now > (app.lastPssTime+PSS_TOP_INTERVAL)) {
|
||||
// For the current top application we will very aggressively collect
|
||||
// PSS data to have a good measure of memory use while in the foreground.
|
||||
requestPssLocked(app, now, true);
|
||||
} else if (app.curAdj <= ProcessList.PERCEPTIBLE_APP_ADJ
|
||||
&& now > (app.lastPssTime+PSS_TOP_INTERVAL)) {
|
||||
// For any unkillable processes, we will more regularly collect their PSS
|
||||
// since they have a significant impact on the memory state of the device.
|
||||
requestPssLocked(app, now, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (app.curAdj != app.setAdj) {
|
||||
@@ -14223,7 +14240,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
app.setAdj = app.curAdj;
|
||||
app.setAdjChanged = true;
|
||||
if (!doingAll) {
|
||||
app.setProcessTrackerState(TOP_APP, mProcessTracker.getMemFactor(),
|
||||
app.setProcessTrackerState(TOP_APP, mProcessTracker.getMemFactorLocked(),
|
||||
now, mProcessList);
|
||||
}
|
||||
} else {
|
||||
@@ -14599,9 +14616,9 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
|
||||
}
|
||||
|
||||
boolean allChanged = mProcessTracker.setMemFactor(memFactor, !mSleeping, now);
|
||||
boolean allChanged = mProcessTracker.setMemFactorLocked(memFactor, !mSleeping, now);
|
||||
if (changed || allChanged) {
|
||||
memFactor = mProcessTracker.getMemFactor();
|
||||
memFactor = mProcessTracker.getMemFactorLocked();
|
||||
for (i=mLruProcesses.size()-1; i>=0; i--) {
|
||||
ProcessRecord app = mLruProcesses.get(i);
|
||||
if (allChanged || app.setAdjChanged) {
|
||||
@@ -14613,6 +14630,16 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
requestPssAllProcsLocked(now, false);
|
||||
}
|
||||
|
||||
if (mProcessTracker.shouldWriteNowLocked(now)) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override public void run() {
|
||||
synchronized (ActivityManagerService.this) {
|
||||
mProcessTracker.writeStateAsyncLocked();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (DEBUG_OOM_ADJ) {
|
||||
Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,8 +16,10 @@
|
||||
|
||||
package com.android.server.am;
|
||||
|
||||
import android.app.AppGlobals;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Binder;
|
||||
@@ -25,8 +27,10 @@ import android.os.IBinder;
|
||||
import android.os.FileUtils;
|
||||
import android.os.Parcel;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.Slog;
|
||||
import android.util.Xml;
|
||||
@@ -93,10 +97,10 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
||||
static IUsageStats sService;
|
||||
private Context mContext;
|
||||
// structure used to maintain statistics since the last checkin.
|
||||
final private Map<String, PkgUsageStatsExtended> mStats;
|
||||
final private ArrayMap<String, PkgUsageStatsExtended> mStats;
|
||||
|
||||
// Maintains the last time any component was resumed, for all time.
|
||||
final private Map<String, Map<String, Long>> mLastResumeTimes;
|
||||
final private ArrayMap<String, ArrayMap<String, Long>> mLastResumeTimes;
|
||||
|
||||
// To remove last-resume time stats when a pacakge is removed.
|
||||
private PackageMonitor mPackageMonitor;
|
||||
@@ -242,8 +246,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
||||
}
|
||||
|
||||
UsageStatsService(String dir) {
|
||||
mStats = new HashMap<String, PkgUsageStatsExtended>();
|
||||
mLastResumeTimes = new HashMap<String, Map<String, Long>>();
|
||||
mStats = new ArrayMap<String, PkgUsageStatsExtended>();
|
||||
mLastResumeTimes = new ArrayMap<String, ArrayMap<String, Long>>();
|
||||
mStatsLock = new Object();
|
||||
mFileLock = new Object();
|
||||
mDir = new File(dir);
|
||||
@@ -386,9 +390,9 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
||||
try {
|
||||
long lastResumeTime = Long.parseLong(lastResumeTimeStr);
|
||||
synchronized (mStatsLock) {
|
||||
Map<String, Long> lrt = mLastResumeTimes.get(pkg);
|
||||
ArrayMap<String, Long> lrt = mLastResumeTimes.get(pkg);
|
||||
if (lrt == null) {
|
||||
lrt = new HashMap<String, Long>();
|
||||
lrt = new ArrayMap<String, Long>();
|
||||
mLastResumeTimes.put(pkg, lrt);
|
||||
}
|
||||
lrt.put(comp, lastResumeTime);
|
||||
@@ -591,14 +595,15 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
||||
/** Filter out stats for any packages which aren't present anymore. */
|
||||
private void filterHistoryStats() {
|
||||
synchronized (mStatsLock) {
|
||||
// Copy and clear the last resume times map, then copy back stats
|
||||
// for all installed packages.
|
||||
Map<String, Map<String, Long>> tmpLastResumeTimes =
|
||||
new HashMap<String, Map<String, Long>>(mLastResumeTimes);
|
||||
mLastResumeTimes.clear();
|
||||
for (PackageInfo info : mContext.getPackageManager().getInstalledPackages(0)) {
|
||||
if (tmpLastResumeTimes.containsKey(info.packageName)) {
|
||||
mLastResumeTimes.put(info.packageName, tmpLastResumeTimes.get(info.packageName));
|
||||
IPackageManager pm = AppGlobals.getPackageManager();
|
||||
for (int i=0; i<mLastResumeTimes.size(); i++) {
|
||||
String pkg = mLastResumeTimes.keyAt(i);
|
||||
try {
|
||||
if (pm.getPackageUid(pkg, 0) < 0) {
|
||||
mLastResumeTimes.removeAt(i);
|
||||
i--;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -614,13 +619,14 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
||||
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
|
||||
out.startTag(null, "usage-history");
|
||||
synchronized (mStatsLock) {
|
||||
for (Map.Entry<String, Map<String, Long>> pkgEntry : mLastResumeTimes.entrySet()) {
|
||||
for (int i=0; i<mLastResumeTimes.size(); i++) {
|
||||
out.startTag(null, "pkg");
|
||||
out.attribute(null, "name", pkgEntry.getKey());
|
||||
for (Map.Entry<String, Long> compEntry : pkgEntry.getValue().entrySet()) {
|
||||
out.attribute(null, "name", mLastResumeTimes.keyAt(i));
|
||||
ArrayMap<String, Long> comp = mLastResumeTimes.valueAt(i);
|
||||
for (int j=0; j<comp.size(); j++) {
|
||||
out.startTag(null, "comp");
|
||||
out.attribute(null, "name", compEntry.getKey());
|
||||
out.attribute(null, "lrt", compEntry.getValue().toString());
|
||||
out.attribute(null, "name", comp.keyAt(j));
|
||||
out.attribute(null, "lrt", comp.valueAt(j).toString());
|
||||
out.endTag(null, "comp");
|
||||
}
|
||||
out.endTag(null, "pkg");
|
||||
@@ -718,9 +724,9 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
||||
pus.addLaunchCount(mLastResumedComp);
|
||||
}
|
||||
|
||||
Map<String, Long> componentResumeTimes = mLastResumeTimes.get(pkgName);
|
||||
ArrayMap<String, Long> componentResumeTimes = mLastResumeTimes.get(pkgName);
|
||||
if (componentResumeTimes == null) {
|
||||
componentResumeTimes = new HashMap<String, Long>();
|
||||
componentResumeTimes = new ArrayMap<String, Long>();
|
||||
mLastResumeTimes.put(pkgName, componentResumeTimes);
|
||||
}
|
||||
componentResumeTimes.put(mLastResumedComp, System.currentTimeMillis());
|
||||
@@ -814,9 +820,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
||||
return null;
|
||||
}
|
||||
PkgUsageStats retArr[] = new PkgUsageStats[size];
|
||||
int i = 0;
|
||||
for (Map.Entry<String, Map<String, Long>> entry : mLastResumeTimes.entrySet()) {
|
||||
String pkg = entry.getKey();
|
||||
for (int i=0; i<size; i++) {
|
||||
String pkg = mLastResumeTimes.keyAt(i);
|
||||
long usageTime = 0;
|
||||
int launchCount = 0;
|
||||
|
||||
@@ -825,8 +830,8 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
||||
usageTime = pus.mUsageTime;
|
||||
launchCount = pus.mLaunchCount;
|
||||
}
|
||||
retArr[i] = new PkgUsageStats(pkg, launchCount, usageTime, entry.getValue());
|
||||
i++;
|
||||
retArr[i] = new PkgUsageStats(pkg, launchCount, usageTime,
|
||||
mLastResumeTimes.valueAt(i));
|
||||
}
|
||||
return retArr;
|
||||
}
|
||||
@@ -866,6 +871,11 @@ public final class UsageStatsService extends IUsageStats.Stub {
|
||||
}
|
||||
File dFile = new File(mDir, file);
|
||||
String dateStr = file.substring(FILE_PREFIX.length());
|
||||
if (dateStr.length() > 0 && (dateStr.charAt(0) <= '0' || dateStr.charAt(0) >= '9')) {
|
||||
// If the remainder does not start with a number, it is not a date,
|
||||
// so we should ignore it for purposes here.
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
Parcel in = getParcelForFile(dFile);
|
||||
collectDumpInfoFromParcelFLOCK(in, pw, dateStr, isCompactOutput,
|
||||
|
||||
Reference in New Issue
Block a user