diff options
author | 2018-01-10 13:15:40 -0800 | |
---|---|---|
committer | 2018-01-26 15:15:04 -0800 | |
commit | e17b445b6c813f6f9bc93a5e3811128a197ef50b (patch) | |
tree | 38b022068c50b29069bfa51626697e36d69ba6f8 | |
parent | 6521393583be1d361e7fbf7d69184cfa30cb037c (diff) |
Reduce pss collection amount, improve logging.
Tuned rates that we collect PSS, to reduce how much we do
that heavy operation. Added a new way to determine
whether a process has changed to a state for the
"first" time -- now this is when it has gone to that
state for the first time since it was in a lower state.
This will reduce the amount of time we consider a
process to be first to only when it has previously
gone into a higher state than it had before.
Keep track of more fine-grained information about why we
collect a PSS sample (not just internal, but for a single
process, all processes because of a mem state change, all
processes because of a poll).
Started collecting RSS in various places, so we can start
looking at that w.r.t. PSS and see about transitioning to
it is a new primary metric.
Added logging for many of the places where the system
writes its configuration files, so we can more easily
see any bad behavior going on in those areas.
Added some currently disabled code to read smaps directly
instead of using fgets(). Probably won't help, but want
tot test.
Bug: 70859548
Test: atest CtsAppTestCases
Change-Id: I400dba0f3ae9c024df51c946cfa592561028b598
39 files changed, 557 insertions, 303 deletions
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index 33e8c3e47b44..6599391fe1c9 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -116,6 +116,8 @@ public final class Debug /** The proportional set size that is swappable for dalvik heap. */ /** @hide We may want to expose this, eventually. */ public int dalvikSwappablePss; + /** @hide The resident set size for dalvik heap. (Without other Dalvik overhead.) */ + public int dalvikRss; /** The private dirty pages used by dalvik heap. */ public int dalvikPrivateDirty; /** The shared dirty pages used by dalvik heap. */ @@ -138,6 +140,8 @@ public final class Debug /** The proportional set size that is swappable for the native heap. */ /** @hide We may want to expose this, eventually. */ public int nativeSwappablePss; + /** @hide The resident set size for the native heap. */ + public int nativeRss; /** The private dirty pages used by the native heap. */ public int nativePrivateDirty; /** The shared dirty pages used by the native heap. */ @@ -160,6 +164,8 @@ public final class Debug /** The proportional set size that is swappable for everything else. */ /** @hide We may want to expose this, eventually. */ public int otherSwappablePss; + /** @hide The resident set size for everything else. */ + public int otherRss; /** The private dirty pages used by everything else. */ public int otherPrivateDirty; /** The shared dirty pages used by everything else. */ @@ -288,24 +294,26 @@ public final class Debug public static final int NUM_DVK_STATS = 14; /** @hide */ - public static final int NUM_CATEGORIES = 8; + public static final int NUM_CATEGORIES = 9; /** @hide */ - public static final int offsetPss = 0; + public static final int OFFSET_PSS = 0; /** @hide */ - public static final int offsetSwappablePss = 1; + public static final int OFFSET_SWAPPABLE_PSS = 1; /** @hide */ - public static final int offsetPrivateDirty = 2; + public static final int OFFSET_RSS = 2; /** @hide */ - public static final int offsetSharedDirty = 3; + public static final int OFFSET_PRIVATE_DIRTY = 3; /** @hide */ - public static final int offsetPrivateClean = 4; + public static final int OFFSET_SHARED_DIRTY = 4; /** @hide */ - public static final int offsetSharedClean = 5; + public static final int OFFSET_PRIVATE_CLEAN = 5; /** @hide */ - public static final int offsetSwappedOut = 6; + public static final int OFFSET_SHARED_CLEAN = 6; /** @hide */ - public static final int offsetSwappedOutPss = 7; + public static final int OFFSET_SWAPPED_OUT = 7; + /** @hide */ + public static final int OFFSET_SWAPPED_OUT_PSS = 8; private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES]; @@ -337,6 +345,13 @@ public final class Debug } /** + * @hide Return total RSS memory usage in kB. + */ + public int getTotalRss() { + return dalvikRss + nativeRss + otherRss; + } + + /** * Return total private dirty memory usage in kB. */ public int getTotalPrivateDirty() { @@ -382,29 +397,32 @@ public final class Debug /** @hide */ public int getOtherPss(int which) { - return otherStats[which*NUM_CATEGORIES + offsetPss]; + return otherStats[which * NUM_CATEGORIES + OFFSET_PSS]; } - /** @hide */ public int getOtherSwappablePss(int which) { - return otherStats[which*NUM_CATEGORIES + offsetSwappablePss]; + return otherStats[which * NUM_CATEGORIES + OFFSET_SWAPPABLE_PSS]; } + /** @hide */ + public int getOtherRss(int which) { + return otherStats[which * NUM_CATEGORIES + OFFSET_RSS]; + } /** @hide */ public int getOtherPrivateDirty(int which) { - return otherStats[which*NUM_CATEGORIES + offsetPrivateDirty]; + return otherStats[which * NUM_CATEGORIES + OFFSET_PRIVATE_DIRTY]; } /** @hide */ public int getOtherSharedDirty(int which) { - return otherStats[which*NUM_CATEGORIES + offsetSharedDirty]; + return otherStats[which * NUM_CATEGORIES + OFFSET_SHARED_DIRTY]; } /** @hide */ public int getOtherPrivateClean(int which) { - return otherStats[which*NUM_CATEGORIES + offsetPrivateClean]; + return otherStats[which * NUM_CATEGORIES + OFFSET_PRIVATE_CLEAN]; } /** @hide */ @@ -414,17 +432,17 @@ public final class Debug /** @hide */ public int getOtherSharedClean(int which) { - return otherStats[which*NUM_CATEGORIES + offsetSharedClean]; + return otherStats[which * NUM_CATEGORIES + OFFSET_SHARED_CLEAN]; } /** @hide */ public int getOtherSwappedOut(int which) { - return otherStats[which*NUM_CATEGORIES + offsetSwappedOut]; + return otherStats[which * NUM_CATEGORIES + OFFSET_SWAPPED_OUT]; } /** @hide */ public int getOtherSwappedOutPss(int which) { - return otherStats[which*NUM_CATEGORIES + offsetSwappedOutPss]; + return otherStats[which * NUM_CATEGORIES + OFFSET_SWAPPED_OUT_PSS]; } /** @hide */ @@ -741,6 +759,7 @@ public final class Debug public void writeToParcel(Parcel dest, int flags) { dest.writeInt(dalvikPss); dest.writeInt(dalvikSwappablePss); + dest.writeInt(dalvikRss); dest.writeInt(dalvikPrivateDirty); dest.writeInt(dalvikSharedDirty); dest.writeInt(dalvikPrivateClean); @@ -749,6 +768,7 @@ public final class Debug dest.writeInt(dalvikSwappedOutPss); dest.writeInt(nativePss); dest.writeInt(nativeSwappablePss); + dest.writeInt(nativeRss); dest.writeInt(nativePrivateDirty); dest.writeInt(nativeSharedDirty); dest.writeInt(nativePrivateClean); @@ -757,6 +777,7 @@ public final class Debug dest.writeInt(nativeSwappedOutPss); dest.writeInt(otherPss); dest.writeInt(otherSwappablePss); + dest.writeInt(otherRss); dest.writeInt(otherPrivateDirty); dest.writeInt(otherSharedDirty); dest.writeInt(otherPrivateClean); @@ -770,6 +791,7 @@ public final class Debug public void readFromParcel(Parcel source) { dalvikPss = source.readInt(); dalvikSwappablePss = source.readInt(); + dalvikRss = source.readInt(); dalvikPrivateDirty = source.readInt(); dalvikSharedDirty = source.readInt(); dalvikPrivateClean = source.readInt(); @@ -778,6 +800,7 @@ public final class Debug dalvikSwappedOutPss = source.readInt(); nativePss = source.readInt(); nativeSwappablePss = source.readInt(); + nativeRss = source.readInt(); nativePrivateDirty = source.readInt(); nativeSharedDirty = source.readInt(); nativePrivateClean = source.readInt(); @@ -786,6 +809,7 @@ public final class Debug nativeSwappedOutPss = source.readInt(); otherPss = source.readInt(); otherSwappablePss = source.readInt(); + otherRss = source.readInt(); otherPrivateDirty = source.readInt(); otherSharedDirty = source.readInt(); otherPrivateClean = source.readInt(); diff --git a/core/java/android/util/AtomicFile.java b/core/java/android/util/AtomicFile.java index 6342c8bcb85e..cf7ed9b0566d 100644 --- a/core/java/android/util/AtomicFile.java +++ b/core/java/android/util/AtomicFile.java @@ -17,6 +17,7 @@ package android.util; import android.os.FileUtils; +import android.os.SystemClock; import libcore.io.IoUtils; @@ -47,14 +48,25 @@ import java.util.function.Consumer; public class AtomicFile { private final File mBaseName; private final File mBackupName; + private final String mCommitTag; + private long mStartTime; /** * Create a new AtomicFile for a file located at the given File path. * The secondary backup file will be the same file path with ".bak" appended. */ public AtomicFile(File baseName) { + this(baseName, null); + } + + /** + * @hide Internal constructor that also allows you to have the class + * automatically log commit events. + */ + public AtomicFile(File baseName, String commitTag) { mBaseName = baseName; mBackupName = new File(baseName.getPath() + ".bak"); + mCommitTag = commitTag; } /** @@ -88,6 +100,18 @@ public class AtomicFile { * access to AtomicFile. */ public FileOutputStream startWrite() throws IOException { + return startWrite(mCommitTag != null ? SystemClock.uptimeMillis() : 0); + } + + /** + * @hide Internal version of {@link #startWrite()} that allows you to specify an earlier + * start time of the operation to adjust how the commit is logged. + * @param startTime The effective start time of the operation, in the time + * base of {@link SystemClock#uptimeMillis()}. + */ + public FileOutputStream startWrite(long startTime) throws IOException { + mStartTime = startTime; + // Rename the current file so it may be used as a backup during the next read if (mBaseName.exists()) { if (!mBackupName.exists()) { @@ -135,6 +159,10 @@ public class AtomicFile { } catch (IOException e) { Log.w("AtomicFile", "finishWrite: Got exception:", e); } + if (mCommitTag != null) { + com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( + mCommitTag, SystemClock.uptimeMillis() - mStartTime); + } } } diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java index a0be64b85d1a..4c263767b5ba 100644 --- a/core/java/com/android/internal/app/procstats/ProcessState.java +++ b/core/java/com/android/internal/app/procstats/ProcessState.java @@ -17,25 +17,18 @@ package com.android.internal.app.procstats; import android.os.Parcel; -import android.os.Parcelable; import android.os.SystemClock; -import android.os.SystemProperties; import android.os.UserHandle; -import android.service.pm.PackageProto; import android.service.procstats.ProcessStatsProto; -import android.text.format.DateFormat; import android.util.ArrayMap; -import android.util.ArraySet; import android.util.DebugUtils; import android.util.Log; import android.util.LongSparseArray; import android.util.Slog; -import android.util.SparseArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; -import com.android.internal.app.procstats.ProcessStats; import com.android.internal.app.procstats.ProcessStats.PackageState; import com.android.internal.app.procstats.ProcessStats.ProcessStateHolder; import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection; @@ -43,6 +36,9 @@ import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT; import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_MAXIMUM; +import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MINIMUM; +import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_AVERAGE; +import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MAXIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_USS_AVERAGE; import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM; @@ -64,20 +60,10 @@ import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_ACTIV import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_EMPTY; import static com.android.internal.app.procstats.ProcessStats.STATE_COUNT; -import dalvik.system.VMRuntime; -import libcore.util.EmptyArray; - -import java.io.IOException; -import java.io.InputStream; import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.Objects; public final class ProcessState { private static final String TAG = "ProcessStats"; @@ -469,13 +455,21 @@ public final class ProcessState { } } - public void addPss(long pss, long uss, boolean always, int type, long duration, + public void addPss(long pss, long uss, long rss, boolean always, int type, long duration, ArrayMap<String, ProcessStateHolder> pkgList) { ensureNotDead(); switch (type) { - case ProcessStats.ADD_PSS_INTERNAL: - mStats.mInternalPssCount++; - mStats.mInternalPssTime += duration; + case ProcessStats.ADD_PSS_INTERNAL_SINGLE: + mStats.mInternalSinglePssCount++; + mStats.mInternalSinglePssTime += duration; + break; + case ProcessStats.ADD_PSS_INTERNAL_ALL_MEM: + mStats.mInternalAllMemPssCount++; + mStats.mInternalAllMemPssTime += duration; + break; + case ProcessStats.ADD_PSS_INTERNAL_ALL_POLL: + mStats.mInternalAllPollPssCount++; + mStats.mInternalAllPollPssTime += duration; break; case ProcessStats.ADD_PSS_EXTERNAL: mStats.mExternalPssCount++; @@ -496,7 +490,8 @@ public final class ProcessState { mLastPssTime = SystemClock.uptimeMillis(); if (mCurState != STATE_NOTHING) { // First update the common process. - mCommonProcess.mPssTable.mergeStats(mCurState, 1, pss, pss, pss, uss, uss, uss); + mCommonProcess.mPssTable.mergeStats(mCurState, 1, pss, pss, pss, uss, uss, uss, + rss, rss, rss); // If the common process is not multi-package, there is nothing else to do. if (!mCommonProcess.mMultiPackage) { @@ -506,7 +501,7 @@ public final class ProcessState { if (pkgList != null) { for (int ip=pkgList.size()-1; ip>=0; ip--) { pullFixedProc(pkgList, ip).mPssTable.mergeStats(mCurState, 1, - pss, pss, pss, uss, uss, uss); + pss, pss, pss, uss, uss, uss, rss, rss, rss); } } } @@ -658,6 +653,18 @@ public final class ProcessState { return mPssTable.getValueForId((byte)state, PSS_USS_MAXIMUM); } + public long getPssRssMinimum(int state) { + return mPssTable.getValueForId((byte)state, PSS_RSS_MINIMUM); + } + + public long getPssRssAverage(int state) { + return mPssTable.getValueForId((byte)state, PSS_RSS_AVERAGE); + } + + public long getPssRssMaximum(int state) { + return mPssTable.getValueForId((byte)state, PSS_RSS_MAXIMUM); + } + /** * Sums up the PSS data and adds it to 'data'. * @@ -793,6 +800,8 @@ public final class ProcessState { new int[] {STATE_SERVICE_RESTARTING}, now, totalTime, true); dumpProcessSummaryDetails(pw, prefix, " Receiver: ", screenStates, memStates, new int[] {STATE_RECEIVER}, now, totalTime, true); + dumpProcessSummaryDetails(pw, prefix, " Heavy: ", screenStates, memStates, + new int[] {STATE_HOME}, now, totalTime, true); dumpProcessSummaryDetails(pw, prefix, " (Home): ", screenStates, memStates, new int[] {STATE_HOME}, now, totalTime, true); dumpProcessSummaryDetails(pw, prefix, " (Last Act): ", screenStates, memStates, @@ -897,6 +906,12 @@ public final class ProcessState { DebugUtils.printSizeValue(pw, getPssUssAverage(bucket) * 1024); pw.print(" "); DebugUtils.printSizeValue(pw, getPssUssMaximum(bucket) * 1024); + pw.print(" / "); + DebugUtils.printSizeValue(pw, getPssRssMinimum(bucket) * 1024); + pw.print(" "); + DebugUtils.printSizeValue(pw, getPssRssAverage(bucket) * 1024); + pw.print(" "); + DebugUtils.printSizeValue(pw, getPssRssMaximum(bucket) * 1024); pw.println(); } } @@ -969,7 +984,8 @@ public final class ProcessState { public void computeProcessData(ProcessStats.ProcessDataCollection data, long now) { data.totalTime = 0; data.numPss = data.minPss = data.avgPss = data.maxPss = - data.minUss = data.avgUss = data.maxUss = 0; + data.minUss = data.avgUss = data.maxUss = + data.minRss = data.avgRss = data.maxRss = 0; for (int is=0; is<data.screenStates.length; is++) { for (int im=0; im<data.memStates.length; im++) { for (int ip=0; ip<data.procStates.length; ip++) { @@ -984,6 +1000,9 @@ public final class ProcessState { long minUss = getPssUssMinimum(bucket); long avgUss = getPssUssAverage(bucket); long maxUss = getPssUssMaximum(bucket); + long minRss = getPssRssMinimum(bucket); + long avgRss = getPssRssAverage(bucket); + long maxRss = getPssRssMaximum(bucket); if (data.numPss == 0) { data.minPss = minPss; data.avgPss = avgPss; @@ -991,6 +1010,9 @@ public final class ProcessState { data.minUss = minUss; data.avgUss = avgUss; data.maxUss = maxUss; + data.minRss = minRss; + data.avgRss = avgRss; + data.maxRss = maxRss; } else { if (minPss < data.minPss) { data.minPss = minPss; @@ -1008,6 +1030,14 @@ public final class ProcessState { if (maxUss > data.maxUss) { data.maxUss = maxUss; } + if (minRss < data.minRss) { + data.minRss = minRss; + } + data.avgRss = (long)( ((data.avgRss*(double)data.numPss) + + (avgRss*(double)samples)) / (data.numPss+samples) ); + if (maxRss > data.maxRss) { + data.maxRss = maxRss; + } } data.numPss += samples; } @@ -1176,6 +1206,12 @@ public final class ProcessState { pw.print(mPssTable.getValue(key, PSS_USS_AVERAGE)); pw.print(':'); pw.print(mPssTable.getValue(key, PSS_USS_MAXIMUM)); + pw.print(':'); + pw.print(mPssTable.getValue(key, PSS_RSS_MINIMUM)); + pw.print(':'); + pw.print(mPssTable.getValue(key, PSS_RSS_AVERAGE)); + pw.print(':'); + pw.print(mPssTable.getValue(key, PSS_RSS_MAXIMUM)); } } @@ -1247,6 +1283,10 @@ public final class ProcessState { mPssTable.getValue(key, PSS_USS_MINIMUM), mPssTable.getValue(key, PSS_USS_AVERAGE), mPssTable.getValue(key, PSS_USS_MAXIMUM)); + ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.RSS, + mPssTable.getValue(key, PSS_RSS_MINIMUM), + mPssTable.getValue(key, PSS_RSS_AVERAGE), + mPssTable.getValue(key, PSS_RSS_MAXIMUM)); proto.end(stateToken); } diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java index 35b2dd23a831..84ddab6c96d9 100644 --- a/core/java/com/android/internal/app/procstats/ProcessStats.java +++ b/core/java/com/android/internal/app/procstats/ProcessStats.java @@ -27,7 +27,6 @@ import android.text.format.DateFormat; import android.util.ArrayMap; import android.util.ArraySet; import android.util.DebugUtils; -import android.util.Log; import android.util.LongSparseArray; import android.util.Slog; import android.util.SparseArray; @@ -35,16 +34,8 @@ import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import com.android.internal.app.ProcessMap; -import com.android.internal.app.procstats.DurationsTable; -import com.android.internal.app.procstats.ProcessState; -import com.android.internal.app.procstats.PssTable; -import com.android.internal.app.procstats.ServiceState; -import com.android.internal.app.procstats.SparseMappingTable; -import com.android.internal.app.procstats.SysMemUsageTable; -import com.android.internal.app.procstats.DumpUtils.*; import dalvik.system.VMRuntime; -import libcore.util.EmptyArray; import java.io.BufferedReader; import java.io.FileReader; @@ -54,7 +45,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; import java.util.Objects; import java.util.regex.Pattern; import java.util.regex.Matcher; @@ -99,7 +89,10 @@ public final class ProcessStats implements Parcelable { public static final int PSS_USS_MINIMUM = 4; public static final int PSS_USS_AVERAGE = 5; public static final int PSS_USS_MAXIMUM = 6; - public static final int PSS_COUNT = PSS_USS_MAXIMUM+1; + public static final int PSS_RSS_MINIMUM = 7; + public static final int PSS_RSS_AVERAGE = 8; + public static final int PSS_RSS_MAXIMUM = 9; + public static final int PSS_COUNT = PSS_RSS_MAXIMUM+1; public static final int SYS_MEM_USAGE_SAMPLE_COUNT = 0; public static final int SYS_MEM_USAGE_CACHED_MINIMUM = 1; @@ -134,9 +127,11 @@ public final class ProcessStats implements Parcelable { public static final int FLAG_SHUTDOWN = 1<<1; public static final int FLAG_SYSPROPS = 1<<2; - public static final int ADD_PSS_INTERNAL = 0; - public static final int ADD_PSS_EXTERNAL = 1; - public static final int ADD_PSS_EXTERNAL_SLOW = 2; + public static final int ADD_PSS_INTERNAL_SINGLE = 0; + public static final int ADD_PSS_INTERNAL_ALL_MEM = 1; + public static final int ADD_PSS_INTERNAL_ALL_POLL = 2; + public static final int ADD_PSS_EXTERNAL = 3; + public static final int ADD_PSS_EXTERNAL_SLOW = 4; public static final int[] ALL_MEM_ADJ = new int[] { ADJ_MEM_FACTOR_NORMAL, ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_LOW, ADJ_MEM_FACTOR_CRITICAL }; @@ -162,7 +157,7 @@ public final class ProcessStats implements Parcelable { }; // Current version of the parcel format. - private static final int PARCEL_VERSION = 24; + private static final int PARCEL_VERSION = 27; // In-memory Parcel magic number, used to detect attempts to unmarshall bad data private static final int MAGIC = 0x50535454; @@ -187,9 +182,17 @@ public final class ProcessStats implements Parcelable { boolean mHasSwappedOutPss; - // Count and total time expended doing "quick" pss computations for internal use. - public long mInternalPssCount; - public long mInternalPssTime; + // Count and total time expended doing "quick" single pss computations for internal use. + public long mInternalSinglePssCount; + public long mInternalSinglePssTime; + + // Count and total time expended doing "quick" all mem pss computations for internal use. + public long mInternalAllMemPssCount; + public long mInternalAllMemPssTime; + + // Count and total time expended doing "quick" all poll pss computations for internal use. + public long mInternalAllPollPssCount; + public long mInternalAllPollPssTime; // Count and total time expended doing "quick" pss computations due to external requests. public long mExternalPssCount; @@ -318,8 +321,12 @@ public final class ProcessStats implements Parcelable { mTimePeriodEndRealtime += other.mTimePeriodEndRealtime - other.mTimePeriodStartRealtime; mTimePeriodEndUptime += other.mTimePeriodEndUptime - other.mTimePeriodStartUptime; - mInternalPssCount += other.mInternalPssCount; - mInternalPssTime += other.mInternalPssTime; + mInternalSinglePssCount += other.mInternalSinglePssCount; + mInternalSinglePssTime += other.mInternalSinglePssTime; + mInternalAllMemPssCount += other.mInternalAllMemPssCount; + mInternalAllMemPssTime += other.mInternalAllMemPssTime; + mInternalAllPollPssCount += other.mInternalAllPollPssCount; + mInternalAllPollPssTime += other.mInternalAllPollPssTime; mExternalPssCount += other.mExternalPssCount; mExternalPssTime += other.mExternalPssTime; mExternalSlowPssCount += other.mExternalSlowPssCount; @@ -523,8 +530,12 @@ public final class ProcessStats implements Parcelable { buildTimePeriodStartClockStr(); mTimePeriodStartRealtime = mTimePeriodEndRealtime = SystemClock.elapsedRealtime(); mTimePeriodStartUptime = mTimePeriodEndUptime = SystemClock.uptimeMillis(); - mInternalPssCount = 0; - mInternalPssTime = 0; + mInternalSinglePssCount = 0; + mInternalSinglePssTime = 0; + mInternalAllMemPssCount = 0; + mInternalAllMemPssTime = 0; + mInternalAllPollPssCount = 0; + mInternalAllPollPssTime = 0; mExternalPssCount = 0; mExternalPssTime = 0; mExternalSlowPssCount = 0; @@ -789,8 +800,12 @@ public final class ProcessStats implements Parcelable { out.writeLong(mTimePeriodEndRealtime); out.writeLong(mTimePeriodStartUptime); out.writeLong(mTimePeriodEndUptime); - out.writeLong(mInternalPssCount); - out.writeLong(mInternalPssTime); + out.writeLong(mInternalSinglePssCount); + out.writeLong(mInternalSinglePssTime); + out.writeLong(mInternalAllMemPssCount); + out.writeLong(mInternalAllMemPssTime); + out.writeLong(mInternalAllPollPssCount); + out.writeLong(mInternalAllPollPssTime); out.writeLong(mExternalPssCount); out.writeLong(mExternalPssTime); out.writeLong(mExternalSlowPssCount); @@ -963,8 +978,12 @@ public final class ProcessStats implements Parcelable { mTimePeriodEndRealtime = in.readLong(); mTimePeriodStartUptime = in.readLong(); mTimePeriodEndUptime = in.readLong(); - mInternalPssCount = in.readLong(); - mInternalPssTime = in.readLong(); + mInternalSinglePssCount = in.readLong(); + mInternalSinglePssTime = in.readLong(); + mInternalAllMemPssCount = in.readLong(); + mInternalAllMemPssTime = in.readLong(); + mInternalAllPollPssCount = in.readLong(); + mInternalAllPollPssTime = in.readLong(); mExternalPssCount = in.readLong(); mExternalPssTime = in.readLong(); mExternalSlowPssCount = in.readLong(); @@ -1526,10 +1545,20 @@ public final class ProcessStats implements Parcelable { totalMem.processStateSamples[STATE_SERVICE_RESTARTING]); pw.println(); pw.println("PSS collection stats:"); - pw.print(" Internal: "); - pw.print(mInternalPssCount); + pw.print(" Internal Single: "); + pw.print(mInternalSinglePssCount); pw.print("x over "); - TimeUtils.formatDuration(mInternalPssTime, pw); + TimeUtils.formatDuration(mInternalSinglePssTime, pw); + pw.println(); + pw.print(" Internal All Procs (Memory Change): "); + pw.print(mInternalAllMemPssCount); + pw.print("x over "); + TimeUtils.formatDuration(mInternalAllMemPssTime, pw); + pw.println(); + pw.print(" Internal All Procs (Polling): "); + pw.print(mInternalAllPollPssCount); + pw.print("x over "); + TimeUtils.formatDuration(mInternalAllPollPssTime, pw); pw.println(); pw.print(" External: "); pw.print(mExternalPssCount); @@ -1854,6 +1883,9 @@ public final class ProcessStats implements Parcelable { public long minUss; public long avgUss; public long maxUss; + public long minRss; + public long avgRss; + public long maxRss; public ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates) { screenStates = _screenStates; @@ -1879,6 +1911,12 @@ public final class ProcessStats implements Parcelable { DebugUtils.printSizeValue(pw, avgUss * 1024); pw.print("-"); DebugUtils.printSizeValue(pw, maxUss * 1024); + pw.print("/"); + DebugUtils.printSizeValue(pw, minRss * 1024); + pw.print("-"); + DebugUtils.printSizeValue(pw, avgRss * 1024); + pw.print("-"); + DebugUtils.printSizeValue(pw, maxRss * 1024); if (full) { pw.print(" over "); pw.print(numPss); diff --git a/core/java/com/android/internal/app/procstats/PssTable.java b/core/java/com/android/internal/app/procstats/PssTable.java index de5f67330423..1e7c566e23a7 100644 --- a/core/java/com/android/internal/app/procstats/PssTable.java +++ b/core/java/com/android/internal/app/procstats/PssTable.java @@ -16,6 +16,9 @@ package com.android.internal.app.procstats; +import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_AVERAGE; +import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MAXIMUM; +import static com.android.internal.app.procstats.ProcessStats.PSS_RSS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT; import static com.android.internal.app.procstats.ProcessStats.PSS_MINIMUM; import static com.android.internal.app.procstats.ProcessStats.PSS_AVERAGE; @@ -51,7 +54,10 @@ public class PssTable extends SparseMappingTable.Table { that.getValue(key, PSS_MAXIMUM), that.getValue(key, PSS_USS_MINIMUM), that.getValue(key, PSS_USS_AVERAGE), - that.getValue(key, PSS_USS_MAXIMUM)); + that.getValue(key, PSS_USS_MAXIMUM), + that.getValue(key, PSS_RSS_MINIMUM), + that.getValue(key, PSS_RSS_AVERAGE), + that.getValue(key, PSS_RSS_MAXIMUM)); } } @@ -60,7 +66,7 @@ public class PssTable extends SparseMappingTable.Table { * one and the new one, the average will now incorporate the new average, etc. */ public void mergeStats(int state, int inCount, long minPss, long avgPss, long maxPss, - long minUss, long avgUss, long maxUss) { + long minUss, long avgUss, long maxUss, long minRss, long avgRss, long maxRss) { final int key = getOrAddKey((byte)state, PSS_COUNT); final long count = getValue(key, PSS_SAMPLE_COUNT); if (count == 0) { @@ -71,6 +77,9 @@ public class PssTable extends SparseMappingTable.Table { setValue(key, PSS_USS_MINIMUM, minUss); setValue(key, PSS_USS_AVERAGE, avgUss); setValue(key, PSS_USS_MAXIMUM, maxUss); + setValue(key, PSS_RSS_MINIMUM, minRss); + setValue(key, PSS_RSS_AVERAGE, avgRss); + setValue(key, PSS_RSS_MAXIMUM, maxRss); } else { setValue(key, PSS_SAMPLE_COUNT, count + inCount); @@ -103,6 +112,20 @@ public class PssTable extends SparseMappingTable.Table { if (val < maxUss) { setValue(key, PSS_USS_MAXIMUM, maxUss); } + + val = getValue(key, PSS_RSS_MINIMUM); + if (val > minUss) { + setValue(key, PSS_RSS_MINIMUM, minUss); + } + + val = getValue(key, PSS_RSS_AVERAGE); + setValue(key, PSS_RSS_AVERAGE, + (long)(((val*(double)count)+(avgUss*(double)inCount)) / (count+inCount))); + + val = getValue(key, PSS_RSS_MAXIMUM); + if (val < maxUss) { + setValue(key, PSS_RSS_MAXIMUM, maxUss); + } } } } diff --git a/core/java/com/android/internal/logging/EventLogTags.logtags b/core/java/com/android/internal/logging/EventLogTags.logtags index a440ee402294..693bd16e6170 100644 --- a/core/java/com/android/internal/logging/EventLogTags.logtags +++ b/core/java/com/android/internal/logging/EventLogTags.logtags @@ -13,3 +13,6 @@ option java_package com.android.internal.logging; # LatencyTracker.java # --------------------------- 36070 sysui_latency (action|1|6),(latency|1|3) + +# Generic event for logging when we write system files. +525000 commit_sys_config_file (name|3),(time|2|3) diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index ee3bec803b51..85b5712c82c0 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -10137,6 +10137,7 @@ public class BatteryStatsImpl extends BatteryStats { updateDailyDeadlineLocked(); if (hasData) { + final long startTime = SystemClock.uptimeMillis(); mDailyItems.add(item); while (mDailyItems.size() > MAX_DAILY_ITEMS) { mDailyItems.remove(0); @@ -10146,10 +10147,12 @@ public class BatteryStatsImpl extends BatteryStats { XmlSerializer out = new FastXmlSerializer(); out.setOutput(memStream, StandardCharsets.UTF_8.name()); writeDailyItemsLocked(out); + final long initialTime = SystemClock.uptimeMillis() - startTime; BackgroundThread.getHandler().post(new Runnable() { @Override public void run() { synchronized (mCheckinFile) { + final long startTime2 = SystemClock.uptimeMillis(); FileOutputStream stream = null; try { stream = mDailyFile.startWrite(); @@ -10158,6 +10161,9 @@ public class BatteryStatsImpl extends BatteryStats { FileUtils.sync(stream); stream.close(); mDailyFile.finishWrite(stream); + com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( + "batterystats-daily", + initialTime + SystemClock.uptimeMillis() - startTime2); } catch (IOException e) { Slog.w("BatteryStats", "Error writing battery daily items", e); @@ -12074,11 +12080,14 @@ public class BatteryStatsImpl extends BatteryStats { // stats to be reported in the next checkin. Only do this if we have // a sufficient amount of data to make it interesting. if (getLowDischargeAmountSinceCharge() >= 20) { + final long startTime = SystemClock.uptimeMillis(); final Parcel parcel = Parcel.obtain(); writeSummaryToParcel(parcel, true); + final long initialTime = SystemClock.uptimeMillis() - startTime; BackgroundThread.getHandler().post(new Runnable() { @Override public void run() { synchronized (mCheckinFile) { + final long startTime2 = SystemClock.uptimeMillis(); FileOutputStream stream = null; try { stream = mCheckinFile.startWrite(); @@ -12087,6 +12096,9 @@ public class BatteryStatsImpl extends BatteryStats { FileUtils.sync(stream); stream.close(); mCheckinFile.finishWrite(stream); + com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( + "batterystats-checkin", + initialTime + SystemClock.uptimeMillis() - startTime2); } catch (IOException e) { Slog.w("BatteryStats", "Error writing checkin battery statistics", e); @@ -13089,12 +13101,15 @@ public class BatteryStatsImpl extends BatteryStats { mWriteLock.lock(); try { + final long startTime = SystemClock.uptimeMillis(); FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite()); stream.write(next.marshall()); stream.flush(); FileUtils.sync(stream); stream.close(); mFile.commit(); + com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( + "batterystats", SystemClock.uptimeMillis() - startTime); } catch (IOException e) { Slog.w("BatteryStats", "Error writing battery statistics", e); mFile.rollback(); diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java index 8848e3939008..e3436e84da71 100644 --- a/core/java/com/android/server/BootReceiver.java +++ b/core/java/com/android/server/BootReceiver.java @@ -85,7 +85,7 @@ public class BootReceiver extends BroadcastReceiver { private static final String LOG_FILES_FILE = "log-files.xml"; private static final AtomicFile sFile = new AtomicFile(new File( - Environment.getDataSystemDirectory(), LOG_FILES_FILE)); + Environment.getDataSystemDirectory(), LOG_FILES_FILE), "log-files"); private static final String LAST_HEADER_FILE = "last-header.txt"; private static final File lastHeaderFile = new File( Environment.getDataSystemDirectory(), LAST_HEADER_FILE); diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index b9ff0a787931..bf183cc8c0aa 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -107,6 +107,7 @@ enum { struct stat_fields { jfieldID pss_field; jfieldID pssSwappable_field; + jfieldID rss_field; jfieldID privateDirty_field; jfieldID sharedDirty_field; jfieldID privateClean_field; @@ -118,6 +119,7 @@ struct stat_fields { struct stat_field_names { const char* pss_name; const char* pssSwappable_name; + const char* rss_name; const char* privateDirty_name; const char* sharedDirty_name; const char* privateClean_name; @@ -129,11 +131,11 @@ struct stat_field_names { static stat_fields stat_fields[_NUM_CORE_HEAP]; static stat_field_names stat_field_names[_NUM_CORE_HEAP] = { - { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", + { "otherPss", "otherSwappablePss", "otherRss", "otherPrivateDirty", "otherSharedDirty", "otherPrivateClean", "otherSharedClean", "otherSwappedOut", "otherSwappedOutPss" }, - { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", + { "dalvikPss", "dalvikSwappablePss", "dalvikRss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikPrivateClean", "dalvikSharedClean", "dalvikSwappedOut", "dalvikSwappedOutPss" }, - { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", + { "nativePss", "nativeSwappablePss", "nativeRss", "nativePrivateDirty", "nativeSharedDirty", "nativePrivateClean", "nativeSharedClean", "nativeSwappedOut", "nativeSwappedOutPss" } }; @@ -143,6 +145,7 @@ jfieldID hasSwappedOutPss_field; struct stats_t { int pss; int swappablePss; + int rss; int privateDirty; int sharedDirty; int privateClean; @@ -246,7 +249,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats, bool* foundSwapPss) int len, nameLen; bool skip, done = false; - unsigned pss = 0, swappable_pss = 0; + unsigned pss = 0, swappable_pss = 0, rss = 0; float sharing_proportion = 0.0; unsigned shared_clean = 0, shared_dirty = 0; unsigned private_clean = 0, private_dirty = 0; @@ -412,7 +415,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats, bool* foundSwapPss) if (line[0] == 'S' && sscanf(line, "Size: %d kB", &temp) == 1) { /* size = temp; */ } else if (line[0] == 'R' && sscanf(line, "Rss: %d kB", &temp) == 1) { - /* resident = temp; */ + rss = temp; } else if (line[0] == 'P' && sscanf(line, "Pss: %d kB", &temp) == 1) { pss = temp; } else if (line[0] == 'S' && sscanf(line, "Shared_Clean: %d kB", &temp) == 1) { @@ -450,6 +453,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats, bool* foundSwapPss) stats[whichHeap].pss += pss; stats[whichHeap].swappablePss += swappable_pss; + stats[whichHeap].rss += rss; stats[whichHeap].privateDirty += private_dirty; stats[whichHeap].sharedDirty += shared_dirty; stats[whichHeap].privateClean += private_clean; @@ -460,6 +464,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats, bool* foundSwapPss) whichHeap == HEAP_DEX || whichHeap == HEAP_ART) { stats[subHeap].pss += pss; stats[subHeap].swappablePss += swappable_pss; + stats[subHeap].rss += rss; stats[subHeap].privateDirty += private_dirty; stats[subHeap].sharedDirty += shared_dirty; stats[subHeap].privateClean += private_clean; @@ -495,15 +500,19 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, if (read_memtrack_memory(pid, &graphics_mem) == 0) { stats[HEAP_GRAPHICS].pss = graphics_mem.graphics; stats[HEAP_GRAPHICS].privateDirty = graphics_mem.graphics; + stats[HEAP_GRAPHICS].rss = graphics_mem.graphics; stats[HEAP_GL].pss = graphics_mem.gl; stats[HEAP_GL].privateDirty = graphics_mem.gl; + stats[HEAP_GL].rss = graphics_mem.gl; stats[HEAP_OTHER_MEMTRACK].pss = graphics_mem.other; stats[HEAP_OTHER_MEMTRACK].privateDirty = graphics_mem.other; + stats[HEAP_OTHER_MEMTRACK].rss = graphics_mem.other; } for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) { stats[HEAP_UNKNOWN].pss += stats[i].pss; stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss; + stats[HEAP_UNKNOWN].rss += stats[i].rss; stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty; stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty; stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean; @@ -515,6 +524,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, for (int i=0; i<_NUM_CORE_HEAP; i++) { env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss); env->SetIntField(object, stat_fields[i].pssSwappable_field, stats[i].swappablePss); + env->SetIntField(object, stat_fields[i].rss_field, stats[i].rss); env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty); env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty); env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean); @@ -536,6 +546,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { otherArray[j++] = stats[i].pss; otherArray[j++] = stats[i].swappablePss; + otherArray[j++] = stats[i].rss; otherArray[j++] = stats[i].privateDirty; otherArray[j++] = stats[i].sharedDirty; otherArray[j++] = stats[i].privateClean; @@ -580,10 +591,11 @@ UniqueFile OpenSmapsOrRollup(int pid) } static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, - jlongArray outUssSwapPss, jlongArray outMemtrack) + jlongArray outUssSwapPssRss, jlongArray outMemtrack) { - char line[1024]; + char lineBuffer[1024]; jlong pss = 0; + jlong rss = 0; jlong swapPss = 0; jlong uss = 0; jlong memtrack = 0; @@ -597,50 +609,70 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, UniqueFile fp = OpenSmapsOrRollup(pid); if (fp != nullptr) { + char* line; + while (true) { - if (fgets(line, sizeof (line), fp.get()) == NULL) { + if (fgets(lineBuffer, sizeof (lineBuffer), fp.get()) == NULL) { break; } - - if (line[0] == 'P') { - if (strncmp(line, "Pss:", 4) == 0) { - char* c = line + 4; - while (*c != 0 && (*c < '0' || *c > '9')) { - c++; + line = lineBuffer; + + switch (line[0]) { + case 'P': + if (strncmp(line, "Pss:", 4) == 0) { + char* c = line + 4; + while (*c != 0 && (*c < '0' || *c > '9')) { + c++; + } + pss += atoi(c); + } else if (strncmp(line, "Private_Clean:", 14) == 0 + || strncmp(line, "Private_Dirty:", 14) == 0) { + char* c = line + 14; + while (*c != 0 && (*c < '0' || *c > '9')) { + c++; + } + uss += atoi(c); } - pss += atoi(c); - } else if (strncmp(line, "Private_Clean:", 14) == 0 - || strncmp(line, "Private_Dirty:", 14) == 0) { - char* c = line + 14; - while (*c != 0 && (*c < '0' || *c > '9')) { - c++; + break; + case 'R': + if (strncmp(line, "Rss:", 4) == 0) { + char* c = line + 4; + while (*c != 0 && (*c < '0' || *c > '9')) { + c++; + } + rss += atoi(c); } - uss += atoi(c); - } - } else if (line[0] == 'S' && strncmp(line, "SwapPss:", 8) == 0) { - char* c = line + 8; - jlong lSwapPss; - while (*c != 0 && (*c < '0' || *c > '9')) { - c++; - } - lSwapPss = atoi(c); - swapPss += lSwapPss; - pss += lSwapPss; // Also in swap, those pages would be accounted as Pss without SWAP + break; + case 'S': + if (strncmp(line, "SwapPss:", 8) == 0) { + char* c = line + 8; + jlong lSwapPss; + while (*c != 0 && (*c < '0' || *c > '9')) { + c++; + } + lSwapPss = atoi(c); + swapPss += lSwapPss; + pss += lSwapPss; // Also in swap, those pages would be accounted as Pss without SWAP + } + break; } } } } - if (outUssSwapPss != NULL) { - if (env->GetArrayLength(outUssSwapPss) >= 1) { - jlong* outUssSwapPssArray = env->GetLongArrayElements(outUssSwapPss, 0); - if (outUssSwapPssArray != NULL) { - outUssSwapPssArray[0] = uss; - if (env->GetArrayLength(outUssSwapPss) >= 2) { - outUssSwapPssArray[1] = swapPss; + if (outUssSwapPssRss != NULL) { + if (env->GetArrayLength(outUssSwapPssRss) >= 1) { + jlong* outUssSwapPssRssArray = env->GetLongArrayElements(outUssSwapPssRss, 0); + if (outUssSwapPssRssArray != NULL) { + outUssSwapPssRssArray[0] = uss; + if (env->GetArrayLength(outUssSwapPssRss) >= 2) { + outUssSwapPssRssArray[1] = swapPss; + } + if (env->GetArrayLength(outUssSwapPssRss) >= 3) { + outUssSwapPssRssArray[2] = rss; } } - env->ReleaseLongArrayElements(outUssSwapPss, outUssSwapPssArray, 0); + env->ReleaseLongArrayElements(outUssSwapPssRss, outUssSwapPssRssArray, 0); } } @@ -1209,6 +1241,8 @@ int register_android_os_Debug(JNIEnv *env) env->GetFieldID(clazz, stat_field_names[i].pss_name, "I"); stat_fields[i].pssSwappable_field = env->GetFieldID(clazz, stat_field_names[i].pssSwappable_name, "I"); + stat_fields[i].rss_field = + env->GetFieldID(clazz, stat_field_names[i].rss_name, "I"); stat_fields[i].privateDirty_field = env->GetFieldID(clazz, stat_field_names[i].privateDirty_name, "I"); stat_fields[i].sharedDirty_field = diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index dec6c0226baa..62aa1f38ca30 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -610,7 +610,7 @@ static jlong getFreeMemoryImpl(const char* const sums[], const size_t sumsLen[], return -1; } - char buffer[256]; + char buffer[2048]; const int len = read(fd, buffer, sizeof(buffer)-1); close(fd); @@ -719,7 +719,7 @@ void android_os_Process_readProcLines(JNIEnv* env, jobject clazz, jstring fileSt int fd = open(file.string(), O_RDONLY | O_CLOEXEC); if (fd >= 0) { - const size_t BUFFER_SIZE = 2048; + const size_t BUFFER_SIZE = 4096; char* buffer = (char*)malloc(BUFFER_SIZE); int len = read(fd, buffer, BUFFER_SIZE-1); close(fd); diff --git a/core/proto/android/service/procstats.proto b/core/proto/android/service/procstats.proto index 4c11f1eb0220..15ede0c5e192 100644 --- a/core/proto/android/service/procstats.proto +++ b/core/proto/android/service/procstats.proto @@ -169,6 +169,9 @@ message ProcessStatsProto { // USS is memory shared between processes, divided evenly for accounting optional android.util.AggStats uss = 7; + + // RSS is memory resident for this process + optional android.util.AggStats rss = 8; } repeated State states = 5; } diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java index 6c7441802d63..f6a259dbf982 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java @@ -889,7 +889,7 @@ public final class PrintSpoolerService extends Service { private PersistenceManager() { mStatePersistFile = new AtomicFile(new File(getFilesDir(), - PERSIST_FILE_NAME)); + PERSIST_FILE_NAME), "print-spooler"); } public void writeStateLocked() { diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java index 793544082af9..5be0176cf4cc 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java @@ -547,7 +547,7 @@ public final class FusedPrintersProvider extends Loader<List<PrinterInfo>> private PersistenceManager(final Activity activity, final int internalLoaderId) { mStatePersistFile = new AtomicFile(new File(activity.getFilesDir(), - PERSIST_FILE_NAME)); + PERSIST_FILE_NAME), "printer-history"); // Initialize enabled services to make sure they are set are the read task might be done // before the loader updated the services the first time. diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java index a8a67abaf8ae..f158a65663f5 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java @@ -166,6 +166,9 @@ final class SettingsState { @GuardedBy("mLock") private final File mStatePersistFile; + @GuardedBy("mLock") + private final String mStatePersistTag; + private final Setting mNullSetting = new Setting(null, null, false, null, null) { @Override public boolean isNull() { @@ -250,6 +253,7 @@ final class SettingsState { mContext = context; mLock = lock; mStatePersistFile = file; + mStatePersistTag = "settings-" + getTypeFromKey(key) + "-" + getUserIdFromKey(key); mKey = key; mHandler = new MyHandler(looper); if (maxBytesPerAppPackage == MAX_BYTES_PER_APP_PACKAGE_LIMITED) { @@ -634,7 +638,7 @@ final class SettingsState { Slog.i(LOG_TAG, "[PERSIST START]"); } - AtomicFile destination = new AtomicFile(mStatePersistFile); + AtomicFile destination = new AtomicFile(mStatePersistFile, mStatePersistTag); FileOutputStream out = null; try { out = destination.startWrite(); diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index f4675fd3316d..894106afc30a 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -39,6 +39,7 @@ import android.os.ResultReceiver; import android.os.ServiceManager; import android.os.ShellCallback; import android.os.ShellCommand; +import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManagerInternal; @@ -248,7 +249,7 @@ public class AppOpsService extends IAppOpsService.Stub { public AppOpsService(File storagePath, Handler handler) { LockGuard.installLock(this, LockGuard.INDEX_APP_OPS); - mFile = new AtomicFile(storagePath); + mFile = new AtomicFile(storagePath, "appops"); mHandler = handler; readState(); } @@ -1666,8 +1667,6 @@ public class AppOpsService extends IAppOpsService.Stub { void writeState() { synchronized (mFile) { - List<AppOpsManager.PackageOps> allOps = getPackagesForOps(null); - FileOutputStream stream; try { stream = mFile.startWrite(); @@ -1676,6 +1675,8 @@ public class AppOpsService extends IAppOpsService.Stub { return; } + List<AppOpsManager.PackageOps> allOps = getPackagesForOps(null); + try { XmlSerializer out = new FastXmlSerializer(); out.setOutput(stream, StandardCharsets.UTF_8.name()); diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index 21137adce69a..fc91d0d7abf1 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -4306,7 +4306,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub Slog.w(TAG, "Couldn't create dir.: " + inputMethodDir.getAbsolutePath()); } final File subtypeFile = new File(inputMethodDir, ADDITIONAL_SUBTYPES_FILE_NAME); - mAdditionalInputMethodSubtypeFile = new AtomicFile(subtypeFile); + mAdditionalInputMethodSubtypeFile = new AtomicFile(subtypeFile, "input-subtypes"); if (!subtypeFile.exists()) { // If "subtypes.xml" doesn't exist, create a blank file. writeAdditionalInputMethodSubtypes( diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 7361e70a5bde..8ec4ef604b4c 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -1386,7 +1386,7 @@ class StorageManagerService extends IStorageManager.Stub } mSettingsFile = new AtomicFile( - new File(Environment.getDataSystemDirectory(), "storage.xml")); + new File(Environment.getDataSystemDirectory(), "storage.xml"), "storage-settings"); synchronized (mLock) { readSettingsLocked(); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index f469437801d3..1e4bacb88a1b 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1643,7 +1643,7 @@ public class ActivityManagerService extends IActivityManager.Stub String mTrackAllocationApp = null; String mNativeDebuggingApp = null; - final long[] mTmpLong = new long[2]; + final long[] mTmpLong = new long[3]; private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet(); @@ -2601,22 +2601,24 @@ public class ActivityManagerService extends IActivityManager.Stub } int num = 0; - long[] tmp = new long[2]; + long[] tmp = new long[3]; do { ProcessRecord proc; int procState; + int statType; int pid; long lastPssTime; synchronized (ActivityManagerService.this) { if (mPendingPssProcesses.size() <= 0) { if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS, - "Collected PSS of " + num + " processes in " + "Collected pss of " + num + " processes in " + (SystemClock.uptimeMillis() - start) + "ms"); mPendingPssProcesses.clear(); return; } proc = mPendingPssProcesses.remove(0); procState = proc.pssProcState; + statType = proc.pssStatType; lastPssTime = proc.lastPssTime; if (proc.thread != null && procState == proc.setProcState && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) @@ -2635,8 +2637,17 @@ public class ActivityManagerService extends IActivityManager.Stub if (pss != 0 && proc.thread != null && proc.setProcState == procState && proc.pid == pid && proc.lastPssTime == lastPssTime) { num++; - recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], - endTime-startTime, SystemClock.uptimeMillis()); + ProcessList.commitNextPssTime(proc.procStateMemTracker); + recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], tmp[2], + statType, endTime-startTime, SystemClock.uptimeMillis()); + } else { + ProcessList.abortNextPssTime(proc.procStateMemTracker); + if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid + + ": " + (proc.thread == null ? "NO_THREAD " : "") + + (proc.pid != pid ? "PID_CHANGED " : "") + + " initState=" + procState + " curState=" + + proc.setProcState + " " + + (proc.lastPssTime != lastPssTime ? "TIME_CHANGED" : "")); } } } @@ -2933,7 +2944,7 @@ public class ActivityManagerService extends IActivityManager.Stub } }); - mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); + mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants"); mUserController = new UserController(this); @@ -6750,7 +6761,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (proc.thread != null && proc.setAdj == oomAdj) { // Record this for posterity if the process has been stable. proc.baseProcessTracker.addPss(infos[i].getTotalPss(), - infos[i].getTotalUss(), false, + infos[i].getTotalUss(), infos[i].getTotalRss(), false, ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime, proc.pkgList); } @@ -6773,7 +6784,7 @@ public class ActivityManagerService extends IActivityManager.Stub oomAdj = proc != null ? proc.setAdj : 0; } } - long[] tmpUss = new long[1]; + long[] tmpUss = new long[3]; long startTime = SystemClock.currentThreadTimeMillis(); pss[i] = Debug.getPss(pids[i], tmpUss, null); long endTime = SystemClock.currentThreadTimeMillis(); @@ -6781,7 +6792,7 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { if (proc.thread != null && proc.setAdj == oomAdj) { // Record this for posterity if the process has been stable. - proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, + proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false, ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList); } } @@ -9940,6 +9951,8 @@ public class ActivityManagerService extends IActivityManager.Stub private void writeGrantedUriPermissions() { if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()"); + final long startTime = SystemClock.uptimeMillis(); + // Snapshot permissions so we can persist without lock ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); synchronized (this) { @@ -9956,7 +9969,7 @@ public class ActivityManagerService extends IActivityManager.Stub FileOutputStream fos = null; try { - fos = mGrantFile.startWrite(); + fos = mGrantFile.startWrite(startTime); XmlSerializer out = new FastXmlSerializer(); out.setOutput(fos, StandardCharsets.UTF_8.name()); @@ -14451,7 +14464,7 @@ public class ActivityManagerService extends IActivityManager.Stub && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) { proc.notCachedSinceIdle = true; proc.initialIdlePss = 0; - proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true, + proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null, mTestPssMode, isSleepingLocked(), now); } } @@ -18381,12 +18394,13 @@ public class ActivityManagerService extends IActivityManager.Stub final long myTotalPss = mi.getTotalPss(); final long myTotalUss = mi.getTotalUss(); + final long myTotalRss = mi.getTotalRss(); final long myTotalSwapPss = mi.getTotalSwappedOutPss(); synchronized (this) { if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { // Record this for posterity if the process has been stable. - r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, + r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true, reportType, endTime-startTime, r.pkgList); } } @@ -18877,12 +18891,13 @@ public class ActivityManagerService extends IActivityManager.Stub final long myTotalPss = mi.getTotalPss(); final long myTotalUss = mi.getTotalUss(); + final long myTotalRss = mi.getTotalRss(); final long myTotalSwapPss = mi.getTotalSwappedOutPss(); synchronized (this) { if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { // Record this for posterity if the process has been stable. - r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, + r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true, reportType, endTime-startTime, r.pkgList); } } @@ -23157,14 +23172,13 @@ public class ActivityManagerService extends IActivityManager.Stub * Record new PSS sample for a process. */ void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss, - long pssDuration, long now) { + long rss, int statType, long pssDuration, long now) { EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024, - swapPss * 1024); + swapPss * 1024, rss * 1024, statType, procState, pssDuration); proc.lastPssTime = now; - proc.baseProcessTracker.addPss(pss, uss, true, ProcessStats.ADD_PSS_INTERNAL, - pssDuration, proc.pkgList); + proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList); if (DEBUG_PSS) Slog.d(TAG_PSS, - "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss + "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss + " state=" + ProcessList.makeProcStateString(procState)); if (proc.initialIdlePss == 0) { proc.initialIdlePss = pss; @@ -23263,8 +23277,9 @@ public class ActivityManagerService extends IActivityManager.Stub if (mPendingPssProcesses.size() == 0) { mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); } - if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc); + if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc); proc.pssProcState = procState; + proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE; mPendingPssProcesses.add(proc); } @@ -23279,7 +23294,7 @@ public class ActivityManagerService extends IActivityManager.Stub return; } } - if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered); + if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs! memLowered=" + memLowered); mLastFullPssTime = now; mFullPssPending = true; mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); @@ -23292,8 +23307,10 @@ public class ActivityManagerService extends IActivityManager.Stub } if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { app.pssProcState = app.setProcState; - app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, - mTestPssMode, isSleepingLocked(), now); + app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL + : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM; + app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, + app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now); mPendingPssProcesses.add(app); } } @@ -23660,16 +23677,16 @@ public class ActivityManagerService extends IActivityManager.Stub long startTime = SystemClock.currentThreadTimeMillis(); long pss = Debug.getPss(app.pid, mTmpLong, null); long endTime = SystemClock.currentThreadTimeMillis(); - recordPssSampleLocked(app, app.curProcState, pss, endTime-startTime, - mTmpLong[0], mTmpLong[1], now); + recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], + mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now); mPendingPssProcesses.remove(app); Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState + " to " + app.curProcState + ": " + (SystemClock.uptimeMillis()-start) + "ms"); } app.lastStateTime = now; - app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, - mTestPssMode, isSleepingLocked(), now); + app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, + app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now); if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from " + ProcessList.makeProcStateString(app.setProcState) + " to " + ProcessList.makeProcStateString(app.curProcState) + " next pss in " @@ -23679,10 +23696,10 @@ public class ActivityManagerService extends IActivityManager.Stub && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( mTestPssMode)))) { requestPssLocked(app, app.setProcState); - app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, - mTestPssMode, isSleepingLocked(), now); + app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, + app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now); } else if (false && DEBUG_PSS) Slog.d(TAG_PSS, - "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); + "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now)); } if (app.setProcState != app.curProcState) { if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) { diff --git a/services/core/java/com/android/server/am/AppWarnings.java b/services/core/java/com/android/server/am/AppWarnings.java index 806e95d71cd1..4b43bd9db201 100644 --- a/services/core/java/com/android/server/am/AppWarnings.java +++ b/services/core/java/com/android/server/am/AppWarnings.java @@ -81,7 +81,7 @@ class AppWarnings { mUiContext = uiContext; mAmsHandler = new ConfigHandler(amsHandler.getLooper()); mUiHandler = new UiHandler(uiHandler.getLooper()); - mConfigFile = new AtomicFile(new File(systemDir, CONFIG_FILE_NAME)); + mConfigFile = new AtomicFile(new File(systemDir, CONFIG_FILE_NAME), "warnings-config"); readConfigFromFileAmsThread(); } diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java index 65c4a42108ec..d84f4879b00f 100644 --- a/services/core/java/com/android/server/am/CompatModePackages.java +++ b/services/core/java/com/android/server/am/CompatModePackages.java @@ -82,7 +82,7 @@ public final class CompatModePackages { public CompatModePackages(ActivityManagerService service, File systemDir, Handler handler) { mService = service; - mFile = new AtomicFile(new File(systemDir, "packages-compat.xml")); + mFile = new AtomicFile(new File(systemDir, "packages-compat.xml"), "compat-mode"); mHandler = new CompatHandler(handler.getLooper()); FileInputStream fis = null; diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags index a131db5c73b0..cb2957daee65 100644 --- a/services/core/java/com/android/server/am/EventLogTags.logtags +++ b/services/core/java/com/android/server/am/EventLogTags.logtags @@ -102,7 +102,7 @@ option java_package com.android.server.am # Report collection of global memory state 30046 am_meminfo (Cached|2|2),(Free|2|2),(Zram|2|2),(Kernel|2|2),(Native|2|2) # Report collection of memory used by a process -30047 am_pss (Pid|1|5),(UID|1|5),(Process Name|3),(Pss|2|2),(Uss|2|2),(SwapPss|2|2) +30047 am_pss (Pid|1|5),(UID|1|5),(Process Name|3),(Pss|2|2),(Uss|2|2),(SwapPss|2|2),(Rss|2|2),(StatType|1|5),(ProcState|1|5),(TimeToCollect|2|2) # Attempting to stop an activity 30048 am_stop_activity (User|1|5),(Token|1|5),(Component Name|3) diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index a50d069f4fef..08ee23723df4 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -21,6 +21,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NA import java.io.IOException; import java.io.OutputStream; +import java.io.PrintWriter; import java.nio.ByteBuffer; import android.app.ActivityManager; @@ -482,7 +483,7 @@ public final class ProcessList { public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000; // The maximum amount of time we want to go between PSS collections. - public static final int PSS_MAX_INTERVAL = 40*60*1000; + public static final int PSS_MAX_INTERVAL = 60*60*1000; // The minimum amount of time between successive PSS requests for *all* processes. public static final int PSS_ALL_INTERVAL = 20*60*1000; @@ -497,7 +498,10 @@ public final class ProcessList { private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000; // The amount of time until PSS when a process first becomes cached. - private static final int PSS_FIRST_CACHED_INTERVAL = 30*1000; + private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000; + + // The amount of time until PSS when an important process stays in the same state. + private static final int PSS_SAME_PERSISTENT_INTERVAL = 20*60*1000; // The amount of time until PSS when the top process stays in the same state. private static final int PSS_SAME_TOP_INTERVAL = 5*60*1000; @@ -509,7 +513,7 @@ public final class ProcessList { private static final int PSS_SAME_SERVICE_INTERVAL = 20*60*1000; // The amount of time until PSS when a cached process stays in the same state. - private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000; + private static final int PSS_SAME_CACHED_INTERVAL = 20*60*1000; // The amount of time until PSS when a persistent process first appears. private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000; @@ -543,7 +547,9 @@ public final class ProcessList { public static final int PROC_MEM_IMPORTANT = 2; public static final int PROC_MEM_SERVICE = 3; public static final int PROC_MEM_CACHED = 4; + public static final int PROC_MEM_NUM = 5; + // Map large set of system process states to private static final int[] sProcStateToProcMem = new int[] { PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI @@ -567,138 +573,96 @@ public final class ProcessList { }; private static final long[] sFirstAwakePssTimes = new long[] { - PSS_FIRST_PERSISTENT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT - PSS_FIRST_PERSISTENT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI - PSS_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP - PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE - PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE - PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND - PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND - PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND - PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP - PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE - PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER - PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING - PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT - PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME - PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY - PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY - PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT - PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_RECENT - PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY + PSS_FIRST_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT + PSS_FIRST_TOP_INTERVAL, // PROC_MEM_TOP + PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT + PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE + PSS_FIRST_CACHED_INTERVAL, // PROC_MEM_CACHED }; private static final long[] sSameAwakePssTimes = new long[] { - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI - PSS_SAME_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP - PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE - PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_RECENT - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY + PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT + PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP + PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT + PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE + PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED }; private static final long[] sFirstAsleepPssTimes = new long[] { - PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT - PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI - PSS_FIRST_ASLEEP_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP - PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE - PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE - PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND - PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND - PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND - PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP - PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE - PSS_FIRST_ASLEEP_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER - PSS_FIRST_ASLEEP_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING - PSS_FIRST_ASLEEP_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT - PSS_FIRST_ASLEEP_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME - PSS_FIRST_ASLEEP_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY - PSS_FIRST_ASLEEP_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY - PSS_FIRST_ASLEEP_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT - PSS_FIRST_ASLEEP_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_RECENT - PSS_FIRST_ASLEEP_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY + PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT + PSS_FIRST_ASLEEP_TOP_INTERVAL, // PROC_MEM_TOP + PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT + PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE + PSS_FIRST_ASLEEP_CACHED_INTERVAL, // PROC_MEM_CACHED }; private static final long[] sSameAsleepPssTimes = new long[] { - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI - PSS_SAME_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND - PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP - PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE - PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_RECENT - PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY + PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT + PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP + PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT + PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE + PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED }; private static final long[] sTestFirstPssTimes = new long[] { - PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT - PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI - PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_RECENT - PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY + PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_PERSISTENT + PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_TOP + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE + PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED }; private static final long[] sTestSamePssTimes = new long[] { - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI - PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP - PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE - PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE - PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND - PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND - PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND - PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_RECENT - PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY + PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_PERSISTENT + PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_TOP + PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT + PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE + PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_CACHED }; + public static final class ProcStateMemTracker { + final int[] mHighestMem = new int[PROC_MEM_NUM]; + int mTotalHighestMem = PROC_MEM_CACHED; + float mCurFactor = 1.0f; + + int mPendingMemState; + int mPendingHighestMemState; + boolean mPendingSame; + + public ProcStateMemTracker() { + for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) { + mHighestMem[i] = PROC_MEM_NUM; + } + mPendingMemState = -1; + } + + public void dumpLine(PrintWriter pw) { + pw.print("best="); + pw.print(mTotalHighestMem); + pw.print(" "); + pw.print(mCurFactor); + pw.print("x ("); + for (int i = 0; i < PROC_MEM_NUM; i++) { + if (i != 0) { + pw.print(", "); + } + pw.print(i); + pw.print("="); + pw.print(mHighestMem[i]); + } + pw.print(")"); + if (mPendingMemState >= 0) { + pw.print(" / pending state="); + pw.print(mPendingMemState); + pw.print(" highest="); + pw.print(mPendingHighestMemState); + pw.print(" same="); + pw.print(mPendingSame); + } + pw.println(); + } + } + public static boolean procStatesDifferForMem(int procState1, int procState2) { return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2]; } @@ -707,16 +671,50 @@ public final class ProcessList { return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE; } - public static long computeNextPssTime(int procState, boolean first, boolean test, + public static void commitNextPssTime(ProcStateMemTracker tracker) { + if (tracker.mPendingMemState >= 0) { + tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState; + tracker.mTotalHighestMem = tracker.mPendingHighestMemState; + if (tracker.mPendingSame) { + tracker.mCurFactor *= 1.5f; + } else { + tracker.mCurFactor = 1; + } + tracker.mPendingMemState = -1; + } + } + + public static void abortNextPssTime(ProcStateMemTracker tracker) { + tracker.mPendingMemState = -1; + } + + public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test, boolean sleeping, long now) { + boolean first; + final int memState = sProcStateToProcMem[procState]; + if (tracker != null) { + final int highestMemState = memState < tracker.mTotalHighestMem + ? memState : tracker.mTotalHighestMem; + first = highestMemState < tracker.mHighestMem[memState]; + tracker.mPendingMemState = memState; + tracker.mPendingHighestMemState = highestMemState; + tracker.mPendingSame = !first; + } else { + first = true; + } final long[] table = test ? (first - ? sTestFirstPssTimes - : sTestSamePssTimes) + ? sTestFirstPssTimes + : sTestSamePssTimes) : (first - ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes) - : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes)); - return now + table[procState]; + ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes) + : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes)); + long delay = (long)(table[memState] * (tracker != null && !first + ? tracker.mCurFactor : 1.0f)); + if (delay > PSS_MAX_INTERVAL) { + delay = PSS_MAX_INTERVAL; + } + return now + delay; } long getMemLevel(int adjustment) { diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 03e140de4ee0..1f6075530412 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -66,6 +66,8 @@ final class ProcessRecord { final String processName; // name of the process // List of packages running in the process final ArrayMap<String, ProcessStats.ProcessStateHolder> pkgList = new ArrayMap<>(); + final ProcessList.ProcStateMemTracker procStateMemTracker + = new ProcessList.ProcStateMemTracker(); UidRecord uidRecord; // overall state of process's uid. ArraySet<String> pkgDeps; // additional packages we have a dependency on IApplicationThread thread; // the actual proc... may be null only if @@ -102,6 +104,7 @@ final class ProcessRecord { int repProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state int setProcState = PROCESS_STATE_NONEXISTENT; // Last set process state in process tracker int pssProcState = PROCESS_STATE_NONEXISTENT; // Currently requesting pss for + int pssStatType; // The type of stat collection that we are currently requesting int savedPriority; // Previous priority value if we're switching to non-SCHED_OTHER int renderThreadTid; // TID for RenderThread boolean serviceb; // Process currently is on the service B list @@ -285,6 +288,7 @@ final class ProcessRecord { TimeUtils.formatDuration(lastActivityTime, nowUptime, pw); pw.print(" lastPssTime="); TimeUtils.formatDuration(lastPssTime, nowUptime, pw); + pw.print(" pssStatType="); pw.print(pssStatType); pw.print(" nextPssTime="); TimeUtils.formatDuration(nextPssTime, nowUptime, pw); pw.println(); @@ -295,6 +299,8 @@ final class ProcessRecord { pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, lastCachedPss*1024); pw.print(" lastCachedSwapPss="); DebugUtils.printSizeValue(pw, lastCachedSwapPss*1024); pw.println(); + pw.print(prefix); pw.print("procStateMemTracker: "); + procStateMemTracker.dumpLine(pw); pw.print(prefix); pw.print("cached="); pw.print(cached); pw.print(" empty="); pw.println(empty); if (serviceb) { diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java index 5f9d61621ede..2963c4fa3faf 100644 --- a/services/core/java/com/android/server/am/ProcessStatsService.java +++ b/services/core/java/com/android/server/am/ProcessStatsService.java @@ -220,8 +220,9 @@ public final class ProcessStatsService extends IProcessStats.Stub { } public void writeStateLocked(boolean sync, final boolean commit) { + final long totalTime; synchronized (mPendingWriteLock) { - long now = SystemClock.uptimeMillis(); + final long now = SystemClock.uptimeMillis(); if (mPendingWrite == null || !mPendingWriteCommitted) { mPendingWrite = Parcel.obtain(); mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime(); @@ -238,19 +239,19 @@ public final class ProcessStatsService extends IProcessStats.Stub { updateFile(); } mLastWriteTime = SystemClock.uptimeMillis(); - if (DEBUG) Slog.d(TAG, "Prepared write state in " - + (SystemClock.uptimeMillis()-now) + "ms"); + totalTime = SystemClock.uptimeMillis() - now; + if (DEBUG) Slog.d(TAG, "Prepared write state in " + now + "ms"); if (!sync) { BackgroundThread.getHandler().post(new Runnable() { @Override public void run() { - performWriteState(); + performWriteState(totalTime); } }); return; } } - performWriteState(); + performWriteState(totalTime); } private void updateFile() { @@ -259,7 +260,7 @@ public final class ProcessStatsService extends IProcessStats.Stub { mLastWriteTime = SystemClock.uptimeMillis(); } - void performWriteState() { + void performWriteState(long initialTime) { if (DEBUG) Slog.d(TAG, "Performing write to " + mFile.getBaseFile()); Parcel data; AtomicFile file; @@ -275,12 +276,15 @@ public final class ProcessStatsService extends IProcessStats.Stub { mWriteLock.lock(); } + final long startTime = SystemClock.uptimeMillis(); FileOutputStream stream = null; try { stream = file.startWrite(); stream.write(data.marshall()); stream.flush(); file.finishWrite(stream); + com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( + "procstats", SystemClock.uptimeMillis() - startTime + initialTime); if (DEBUG) Slog.d(TAG, "Write completed successfully!"); } catch (IOException e) { Slog.w(TAG, "Error writing process statistics", e); diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java index e498666073ed..5a37ee235219 100644 --- a/services/core/java/com/android/server/content/SyncStorageEngine.java +++ b/services/core/java/com/android/server/content/SyncStorageEngine.java @@ -481,9 +481,9 @@ public class SyncStorageEngine { maybeDeleteLegacyPendingInfoLocked(syncDir); - mAccountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml")); - mStatusFile = new AtomicFile(new File(syncDir, "status.bin")); - mStatisticsFile = new AtomicFile(new File(syncDir, "stats.bin")); + mAccountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"), "sync-accounts"); + mStatusFile = new AtomicFile(new File(syncDir, "status.bin"), "sync-status"); + mStatisticsFile = new AtomicFile(new File(syncDir, "stats.bin"), "sync-stats"); readAccountInfoLocked(); readStatusLocked(); diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java index cbf46f832186..1af03de7de2f 100644 --- a/services/core/java/com/android/server/display/PersistentDataStore.java +++ b/services/core/java/com/android/server/display/PersistentDataStore.java @@ -771,7 +771,8 @@ final class PersistentDataStore { private final AtomicFile mAtomicFile; public Injector() { - mAtomicFile = new AtomicFile(new File("/data/system/display-manager-state.xml")); + mAtomicFile = new AtomicFile(new File("/data/system/display-manager-state.xml"), + "display-state"); } public InputStream openRead() throws FileNotFoundException { diff --git a/services/core/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java index f67e0fdee0fb..372db416e756 100644 --- a/services/core/java/com/android/server/input/PersistentDataStore.java +++ b/services/core/java/com/android/server/input/PersistentDataStore.java @@ -82,7 +82,8 @@ final class PersistentDataStore { private boolean mDirty; public PersistentDataStore() { - mAtomicFile = new AtomicFile(new File("/data/system/input-manager-state.xml")); + mAtomicFile = new AtomicFile(new File("/data/system/input-manager-state.xml"), + "input-state"); } public void saveIfNeeded() { diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java index a24a4ac3823b..f4bbf4cf5115 100644 --- a/services/core/java/com/android/server/job/JobStore.java +++ b/services/core/java/com/android/server/job/JobStore.java @@ -29,6 +29,7 @@ import android.os.Environment; import android.os.Handler; import android.os.PersistableBundle; import android.os.Process; +import android.os.SystemClock; import android.os.UserHandle; import android.text.format.DateUtils; import android.util.ArraySet; @@ -133,7 +134,7 @@ public final class JobStore { File systemDir = new File(dataDir, "system"); File jobDir = new File(systemDir, "job"); jobDir.mkdirs(); - mJobsFile = new AtomicFile(new File(jobDir, "jobs.xml")); + mJobsFile = new AtomicFile(new File(jobDir, "jobs.xml"), "jobs"); mJobSet = new JobSet(); @@ -361,6 +362,7 @@ public final class JobStore { int numSystemJobs = 0; int numSyncJobs = 0; try { + final long startTime = SystemClock.uptimeMillis(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); XmlSerializer out = new FastXmlSerializer(); out.setOutput(baos, StandardCharsets.UTF_8.name()); @@ -393,7 +395,7 @@ public final class JobStore { out.endDocument(); // Write out to disk in one fell swoop. - FileOutputStream fos = mJobsFile.startWrite(); + FileOutputStream fos = mJobsFile.startWrite(startTime); fos.write(baos.toByteArray()); mJobsFile.finishWrite(fos); mDirtyOperations = 0; diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 0e54768bfa87..f09de5222715 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -551,7 +551,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mSuppressDefaultPolicy = suppressDefaultPolicy; - mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml")); + mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"), "net-policy"); mAppOps = context.getSystemService(AppOpsManager.class); diff --git a/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java b/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java index b78fe4d2cca7..f5ba889e8cf4 100644 --- a/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java +++ b/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java @@ -77,7 +77,7 @@ class WatchlistSettings { @VisibleForTesting protected WatchlistSettings(File xmlFile) { - mXmlFile = new AtomicFile(xmlFile); + mXmlFile = new AtomicFile(xmlFile, "net-watchlist"); reloadSettings(); if (mPrivacySecretKey == null) { // Generate a new secret key and save settings diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 4c9da8949cc9..6a2b92357f15 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1406,7 +1406,7 @@ public class NotificationManagerService extends SystemService { AppGlobals.getPackageManager()), new ConditionProviders(getContext(), mUserProfiles, AppGlobals.getPackageManager()), null, snoozeHelper, new NotificationUsageStats(getContext()), - new AtomicFile(new File(systemDir, "notification_policy.xml")), + new AtomicFile(new File(systemDir, "notification_policy.xml"), "notification-policy"), (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE), getGroupHelper()); diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index 2041de64c8fb..4bc4a7ecc055 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -228,7 +228,7 @@ public final class OverlayManagerService extends SystemService { @NonNull final Installer installer) { super(context); mSettingsFile = - new AtomicFile(new File(Environment.getDataSystemDirectory(), "overlays.xml")); + new AtomicFile(new File(Environment.getDataSystemDirectory(), "overlays.xml"), "overlays"); mPackageManager = new PackageManagerHelper(); mUserManager = UserManagerService.getInstance(); IdmapManager im = new IdmapManager(installer); diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 16fae99a71c5..59f9dae0619a 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -58,6 +58,7 @@ import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.SELinux; +import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManager; @@ -193,7 +194,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub { mCallbacks = new Callbacks(mInstallThread.getLooper()); mSessionsFile = new AtomicFile( - new File(Environment.getDataSystemDirectory(), "install_sessions.xml")); + new File(Environment.getDataSystemDirectory(), "install_sessions.xml"), + "package-session"); mSessionsDir = new File(Environment.getDataSystemDirectory(), "install_sessions"); mSessionsDir.mkdirs(); } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 8ce412e5783a..de74c303ece7 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1994,6 +1994,8 @@ public final class Settings { if (DEBUG_MU) { Log.i(TAG, "Writing package restrictions for user=" + userId); } + final long startTime = SystemClock.uptimeMillis(); + // Keep the old stopped packages around until we know the new ones have // been successfully written. File userPackagesStateFile = getUserPackagesStateFile(userId); @@ -2127,6 +2129,9 @@ public final class Settings { |FileUtils.S_IRGRP|FileUtils.S_IWGRP, -1, -1); + com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( + "package-user-" + userId, SystemClock.uptimeMillis() - startTime); + // Done, all is good! return; } catch(java.io.IOException e) { @@ -2388,6 +2393,8 @@ public final class Settings { void writeLPr() { //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024); + final long startTime = SystemClock.uptimeMillis(); + // Keep the old settings around until we know the new ones have // been successfully written. if (mSettingsFilename.exists()) { @@ -2533,6 +2540,8 @@ public final class Settings { writePackageListLPr(); writeAllUsersPackageRestrictionsLPr(); writeAllRuntimePermissionsLPr(); + com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( + "package", SystemClock.uptimeMillis() - startTime); return; } catch(java.io.IOException e) { @@ -5131,7 +5140,8 @@ public final class Settings { } private void writePermissionsSync(int userId) { - AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId)); + AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId), + "package-perms-" + userId); ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>(); ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>(); diff --git a/services/core/java/com/android/server/timezone/PackageStatusStorage.java b/services/core/java/com/android/server/timezone/PackageStatusStorage.java index 251a27763fd2..04f0871c9897 100644 --- a/services/core/java/com/android/server/timezone/PackageStatusStorage.java +++ b/services/core/java/com/android/server/timezone/PackageStatusStorage.java @@ -81,7 +81,7 @@ final class PackageStatusStorage { private final AtomicFile mPackageStatusFile; PackageStatusStorage(File storageDir) { - mPackageStatusFile = new AtomicFile(new File(storageDir, "package-status.xml")); + mPackageStatusFile = new AtomicFile(new File(storageDir, "package-status.xml"), "timezone-status"); } /** diff --git a/services/core/java/com/android/server/tv/PersistentDataStore.java b/services/core/java/com/android/server/tv/PersistentDataStore.java index 85a882960575..8f2194c3c8b6 100644 --- a/services/core/java/com/android/server/tv/PersistentDataStore.java +++ b/services/core/java/com/android/server/tv/PersistentDataStore.java @@ -91,7 +91,7 @@ final class PersistentDataStore { throw new IllegalStateException("User dir cannot be created: " + userDir); } } - mAtomicFile = new AtomicFile(new File(userDir, "tv-input-manager-state.xml")); + mAtomicFile = new AtomicFile(new File(userDir, "tv-input-manager-state.xml"), "tv-input-state"); } public boolean isParentalControlsEnabled() { diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java index 7f7968610151..97b64dc2b6b1 100644 --- a/services/core/java/com/android/server/wm/DisplaySettings.java +++ b/services/core/java/com/android/server/wm/DisplaySettings.java @@ -64,7 +64,7 @@ public class DisplaySettings { public DisplaySettings() { File dataDir = Environment.getDataDirectory(); File systemDir = new File(dataDir, "system"); - mFile = new AtomicFile(new File(systemDir, "display_settings.xml")); + mFile = new AtomicFile(new File(systemDir, "display_settings.xml"), "wm-displays"); } public void getOverscanLocked(String name, String uniqueId, Rect outRect) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java b/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java index 6a9b53a0a2df..a17a1075f100 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PasswordBlacklist.java @@ -47,7 +47,7 @@ public class PasswordBlacklist { * This is a lightweight operation to prepare variables but not perform any IO. */ public PasswordBlacklist(File file) { - mFile = new AtomicFile(file); + mFile = new AtomicFile(file, "device-policy"); } /** diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java index 917e651bb425..5f1f5e496de1 100644 --- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java @@ -208,7 +208,7 @@ class UsbProfileGroupSettingsManager { mParentUser = user; mSettingsFile = new AtomicFile(new File( Environment.getUserSystemDirectory(user.getIdentifier()), - "usb_device_manager.xml")); + "usb_device_manager.xml"), "usb-state"); mDisablePermissionDialogs = context.getResources().getBoolean( com.android.internal.R.bool.config_disableUsbPermissionDialogs); |