Merge "More work on procstats: save/restore state, fixes."

This commit is contained in:
Dianne Hackborn
2013-06-29 02:14:10 +00:00
committed by Android (Google) Code Review
6 changed files with 903 additions and 356 deletions

View File

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

View File

@@ -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

View File

@@ -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,