ProcessStats.java revision 676d1ace1cc57d2335bfaabd92284d52d8fc4edf
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.app.procstats; 18 19import android.os.Debug; 20import android.os.Parcel; 21import android.os.Parcelable; 22import android.os.SystemClock; 23import android.os.SystemProperties; 24import android.os.UserHandle; 25import android.service.procstats.ProcessStatsSectionProto; 26import android.text.format.DateFormat; 27import android.util.ArrayMap; 28import android.util.ArraySet; 29import android.util.DebugUtils; 30import android.util.Log; 31import android.util.LongSparseArray; 32import android.util.Slog; 33import android.util.SparseArray; 34import android.util.TimeUtils; 35import android.util.proto.ProtoOutputStream; 36 37import com.android.internal.app.ProcessMap; 38import com.android.internal.app.procstats.DurationsTable; 39import com.android.internal.app.procstats.ProcessState; 40import com.android.internal.app.procstats.PssTable; 41import com.android.internal.app.procstats.ServiceState; 42import com.android.internal.app.procstats.SparseMappingTable; 43import com.android.internal.app.procstats.SysMemUsageTable; 44import com.android.internal.app.procstats.DumpUtils.*; 45 46import dalvik.system.VMRuntime; 47import libcore.util.EmptyArray; 48 49import java.io.BufferedReader; 50import java.io.FileReader; 51import java.io.IOException; 52import java.io.InputStream; 53import java.io.PrintWriter; 54import java.util.ArrayList; 55import java.util.Arrays; 56import java.util.Collections; 57import java.util.Comparator; 58import java.util.Objects; 59import java.util.regex.Pattern; 60import java.util.regex.Matcher; 61 62public final class ProcessStats implements Parcelable { 63 public static final String TAG = "ProcessStats"; 64 static final boolean DEBUG = false; 65 static final boolean DEBUG_PARCEL = false; 66 67 public static final String SERVICE_NAME = "procstats"; 68 69 // How often the service commits its data, giving the minimum batching 70 // that is done. 71 public static long COMMIT_PERIOD = 3*60*60*1000; // Commit current stats every 3 hours 72 73 // Minimum uptime period before committing. If the COMMIT_PERIOD has elapsed but 74 // the total uptime has not exceeded this amount, then the commit will be held until 75 // it is reached. 76 public static long COMMIT_UPTIME_PERIOD = 60*60*1000; // Must have at least 1 hour elapsed 77 78 public static final int STATE_NOTHING = -1; 79 public static final int STATE_PERSISTENT = 0; 80 public static final int STATE_TOP = 1; 81 public static final int STATE_IMPORTANT_FOREGROUND = 2; 82 public static final int STATE_IMPORTANT_BACKGROUND = 3; 83 public static final int STATE_BACKUP = 4; 84 public static final int STATE_SERVICE = 5; 85 public static final int STATE_SERVICE_RESTARTING = 6; 86 public static final int STATE_RECEIVER = 7; 87 public static final int STATE_HEAVY_WEIGHT = 8; 88 public static final int STATE_HOME = 9; 89 public static final int STATE_LAST_ACTIVITY = 10; 90 public static final int STATE_CACHED_ACTIVITY = 11; 91 public static final int STATE_CACHED_ACTIVITY_CLIENT = 12; 92 public static final int STATE_CACHED_EMPTY = 13; 93 public static final int STATE_COUNT = STATE_CACHED_EMPTY+1; 94 95 public static final int PSS_SAMPLE_COUNT = 0; 96 public static final int PSS_MINIMUM = 1; 97 public static final int PSS_AVERAGE = 2; 98 public static final int PSS_MAXIMUM = 3; 99 public static final int PSS_USS_MINIMUM = 4; 100 public static final int PSS_USS_AVERAGE = 5; 101 public static final int PSS_USS_MAXIMUM = 6; 102 public static final int PSS_COUNT = PSS_USS_MAXIMUM+1; 103 104 public static final int SYS_MEM_USAGE_SAMPLE_COUNT = 0; 105 public static final int SYS_MEM_USAGE_CACHED_MINIMUM = 1; 106 public static final int SYS_MEM_USAGE_CACHED_AVERAGE = 2; 107 public static final int SYS_MEM_USAGE_CACHED_MAXIMUM = 3; 108 public static final int SYS_MEM_USAGE_FREE_MINIMUM = 4; 109 public static final int SYS_MEM_USAGE_FREE_AVERAGE = 5; 110 public static final int SYS_MEM_USAGE_FREE_MAXIMUM = 6; 111 public static final int SYS_MEM_USAGE_ZRAM_MINIMUM = 7; 112 public static final int SYS_MEM_USAGE_ZRAM_AVERAGE = 8; 113 public static final int SYS_MEM_USAGE_ZRAM_MAXIMUM = 9; 114 public static final int SYS_MEM_USAGE_KERNEL_MINIMUM = 10; 115 public static final int SYS_MEM_USAGE_KERNEL_AVERAGE = 11; 116 public static final int SYS_MEM_USAGE_KERNEL_MAXIMUM = 12; 117 public static final int SYS_MEM_USAGE_NATIVE_MINIMUM = 13; 118 public static final int SYS_MEM_USAGE_NATIVE_AVERAGE = 14; 119 public static final int SYS_MEM_USAGE_NATIVE_MAXIMUM = 15; 120 public static final int SYS_MEM_USAGE_COUNT = SYS_MEM_USAGE_NATIVE_MAXIMUM+1; 121 122 public static final int ADJ_NOTHING = -1; 123 public static final int ADJ_MEM_FACTOR_NORMAL = 0; 124 public static final int ADJ_MEM_FACTOR_MODERATE = 1; 125 public static final int ADJ_MEM_FACTOR_LOW = 2; 126 public static final int ADJ_MEM_FACTOR_CRITICAL = 3; 127 public static final int ADJ_MEM_FACTOR_COUNT = ADJ_MEM_FACTOR_CRITICAL+1; 128 public static final int ADJ_SCREEN_MOD = ADJ_MEM_FACTOR_COUNT; 129 public static final int ADJ_SCREEN_OFF = 0; 130 public static final int ADJ_SCREEN_ON = ADJ_SCREEN_MOD; 131 public static final int ADJ_COUNT = ADJ_SCREEN_ON*2; 132 133 public static final int FLAG_COMPLETE = 1<<0; 134 public static final int FLAG_SHUTDOWN = 1<<1; 135 public static final int FLAG_SYSPROPS = 1<<2; 136 137 public static final int ADD_PSS_INTERNAL = 0; 138 public static final int ADD_PSS_EXTERNAL = 1; 139 public static final int ADD_PSS_EXTERNAL_SLOW = 2; 140 141 public static final int[] ALL_MEM_ADJ = new int[] { ADJ_MEM_FACTOR_NORMAL, 142 ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_LOW, ADJ_MEM_FACTOR_CRITICAL }; 143 144 public static final int[] ALL_SCREEN_ADJ = new int[] { ADJ_SCREEN_OFF, ADJ_SCREEN_ON }; 145 146 public static final int[] NON_CACHED_PROC_STATES = new int[] { 147 STATE_PERSISTENT, STATE_TOP, STATE_IMPORTANT_FOREGROUND, 148 STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, 149 STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER, STATE_HEAVY_WEIGHT 150 }; 151 152 public static final int[] BACKGROUND_PROC_STATES = new int[] { 153 STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, 154 STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER 155 }; 156 157 public static final int[] ALL_PROC_STATES = new int[] { STATE_PERSISTENT, 158 STATE_TOP, STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, 159 STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER, 160 STATE_HEAVY_WEIGHT, STATE_HOME, STATE_LAST_ACTIVITY, STATE_CACHED_ACTIVITY, 161 STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY 162 }; 163 164 // Current version of the parcel format. 165 private static final int PARCEL_VERSION = 24; 166 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data 167 private static final int MAGIC = 0x50535454; 168 169 public String mReadError; 170 public String mTimePeriodStartClockStr; 171 public int mFlags; 172 173 public final ProcessMap<LongSparseArray<PackageState>> mPackages = new ProcessMap<>(); 174 public final ProcessMap<ProcessState> mProcesses = new ProcessMap<>(); 175 176 public final long[] mMemFactorDurations = new long[ADJ_COUNT]; 177 public int mMemFactor = STATE_NOTHING; 178 public long mStartTime; 179 180 public long mTimePeriodStartClock; 181 public long mTimePeriodStartRealtime; 182 public long mTimePeriodEndRealtime; 183 public long mTimePeriodStartUptime; 184 public long mTimePeriodEndUptime; 185 String mRuntime; 186 boolean mRunning; 187 188 boolean mHasSwappedOutPss; 189 190 // Count and total time expended doing "quick" pss computations for internal use. 191 public long mInternalPssCount; 192 public long mInternalPssTime; 193 194 // Count and total time expended doing "quick" pss computations due to external requests. 195 public long mExternalPssCount; 196 public long mExternalPssTime; 197 198 // Count and total time expended doing full/slow pss computations due to external requests. 199 public long mExternalSlowPssCount; 200 public long mExternalSlowPssTime; 201 202 public final SparseMappingTable mTableData = new SparseMappingTable(); 203 204 public final long[] mSysMemUsageArgs = new long[SYS_MEM_USAGE_COUNT]; 205 public final SysMemUsageTable mSysMemUsage = new SysMemUsageTable(mTableData); 206 207 // For writing parcels. 208 ArrayMap<String, Integer> mCommonStringToIndex; 209 210 // For reading parcels. 211 ArrayList<String> mIndexToCommonString; 212 213 private static final Pattern sPageTypeRegex = Pattern.compile( 214 "^Node\\s+(\\d+),.*. type\\s+(\\w+)\\s+([\\s\\d]+?)\\s*$"); 215 private final ArrayList<Integer> mPageTypeZones = new ArrayList<Integer>(); 216 private final ArrayList<String> mPageTypeLabels = new ArrayList<String>(); 217 private final ArrayList<int[]> mPageTypeSizes = new ArrayList<int[]>(); 218 219 public ProcessStats(boolean running) { 220 mRunning = running; 221 reset(); 222 if (running) { 223 // If we are actively running, we need to determine whether the system is 224 // collecting swap pss data. 225 Debug.MemoryInfo info = new Debug.MemoryInfo(); 226 Debug.getMemoryInfo(android.os.Process.myPid(), info); 227 mHasSwappedOutPss = info.hasSwappedOutPss(); 228 } 229 } 230 231 public ProcessStats(Parcel in) { 232 reset(); 233 readFromParcel(in); 234 } 235 236 public void add(ProcessStats other) { 237 ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 238 other.mPackages.getMap(); 239 for (int ip=0; ip<pkgMap.size(); ip++) { 240 final String pkgName = pkgMap.keyAt(ip); 241 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 242 for (int iu=0; iu<uids.size(); iu++) { 243 final int uid = uids.keyAt(iu); 244 final LongSparseArray<PackageState> versions = uids.valueAt(iu); 245 for (int iv=0; iv<versions.size(); iv++) { 246 final long vers = versions.keyAt(iv); 247 final PackageState otherState = versions.valueAt(iv); 248 final int NPROCS = otherState.mProcesses.size(); 249 final int NSRVS = otherState.mServices.size(); 250 for (int iproc=0; iproc<NPROCS; iproc++) { 251 ProcessState otherProc = otherState.mProcesses.valueAt(iproc); 252 if (otherProc.getCommonProcess() != otherProc) { 253 if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid 254 + " vers " + vers + " proc " + otherProc.getName()); 255 ProcessState thisProc = getProcessStateLocked(pkgName, uid, vers, 256 otherProc.getName()); 257 if (thisProc.getCommonProcess() == thisProc) { 258 if (DEBUG) Slog.d(TAG, "Existing process is single-package, splitting"); 259 thisProc.setMultiPackage(true); 260 long now = SystemClock.uptimeMillis(); 261 final PackageState pkgState = getPackageStateLocked(pkgName, uid, 262 vers); 263 thisProc = thisProc.clone(now); 264 pkgState.mProcesses.put(thisProc.getName(), thisProc); 265 } 266 thisProc.add(otherProc); 267 } 268 } 269 for (int isvc=0; isvc<NSRVS; isvc++) { 270 ServiceState otherSvc = otherState.mServices.valueAt(isvc); 271 if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid 272 + " service " + otherSvc.getName()); 273 ServiceState thisSvc = getServiceStateLocked(pkgName, uid, vers, 274 otherSvc.getProcessName(), otherSvc.getName()); 275 thisSvc.add(otherSvc); 276 } 277 } 278 } 279 } 280 281 ArrayMap<String, SparseArray<ProcessState>> procMap = other.mProcesses.getMap(); 282 for (int ip=0; ip<procMap.size(); ip++) { 283 SparseArray<ProcessState> uids = procMap.valueAt(ip); 284 for (int iu=0; iu<uids.size(); iu++) { 285 int uid = uids.keyAt(iu); 286 ProcessState otherProc = uids.valueAt(iu); 287 final String name = otherProc.getName(); 288 final String pkg = otherProc.getPackage(); 289 final long vers = otherProc.getVersion(); 290 ProcessState thisProc = mProcesses.get(name, uid); 291 if (DEBUG) Slog.d(TAG, "Adding uid " + uid + " proc " + name); 292 if (thisProc == null) { 293 if (DEBUG) Slog.d(TAG, "Creating new process!"); 294 thisProc = new ProcessState(this, pkg, uid, vers, name); 295 mProcesses.put(name, uid, thisProc); 296 PackageState thisState = getPackageStateLocked(pkg, uid, vers); 297 if (!thisState.mProcesses.containsKey(name)) { 298 thisState.mProcesses.put(name, thisProc); 299 } 300 } 301 thisProc.add(otherProc); 302 } 303 } 304 305 for (int i=0; i<ADJ_COUNT; i++) { 306 if (DEBUG) Slog.d(TAG, "Total duration #" + i + " inc by " 307 + other.mMemFactorDurations[i] + " from " 308 + mMemFactorDurations[i]); 309 mMemFactorDurations[i] += other.mMemFactorDurations[i]; 310 } 311 312 mSysMemUsage.mergeStats(other.mSysMemUsage); 313 314 if (other.mTimePeriodStartClock < mTimePeriodStartClock) { 315 mTimePeriodStartClock = other.mTimePeriodStartClock; 316 mTimePeriodStartClockStr = other.mTimePeriodStartClockStr; 317 } 318 mTimePeriodEndRealtime += other.mTimePeriodEndRealtime - other.mTimePeriodStartRealtime; 319 mTimePeriodEndUptime += other.mTimePeriodEndUptime - other.mTimePeriodStartUptime; 320 321 mInternalPssCount += other.mInternalPssCount; 322 mInternalPssTime += other.mInternalPssTime; 323 mExternalPssCount += other.mExternalPssCount; 324 mExternalPssTime += other.mExternalPssTime; 325 mExternalSlowPssCount += other.mExternalSlowPssCount; 326 mExternalSlowPssTime += other.mExternalSlowPssTime; 327 328 mHasSwappedOutPss |= other.mHasSwappedOutPss; 329 } 330 331 public void addSysMemUsage(long cachedMem, long freeMem, long zramMem, long kernelMem, 332 long nativeMem) { 333 if (mMemFactor != STATE_NOTHING) { 334 int state = mMemFactor * STATE_COUNT; 335 mSysMemUsageArgs[SYS_MEM_USAGE_SAMPLE_COUNT] = 1; 336 for (int i=0; i<3; i++) { 337 mSysMemUsageArgs[SYS_MEM_USAGE_CACHED_MINIMUM + i] = cachedMem; 338 mSysMemUsageArgs[SYS_MEM_USAGE_FREE_MINIMUM + i] = freeMem; 339 mSysMemUsageArgs[SYS_MEM_USAGE_ZRAM_MINIMUM + i] = zramMem; 340 mSysMemUsageArgs[SYS_MEM_USAGE_KERNEL_MINIMUM + i] = kernelMem; 341 mSysMemUsageArgs[SYS_MEM_USAGE_NATIVE_MINIMUM + i] = nativeMem; 342 } 343 mSysMemUsage.mergeStats(state, mSysMemUsageArgs, 0); 344 } 345 } 346 347 public static final Parcelable.Creator<ProcessStats> CREATOR 348 = new Parcelable.Creator<ProcessStats>() { 349 public ProcessStats createFromParcel(Parcel in) { 350 return new ProcessStats(in); 351 } 352 353 public ProcessStats[] newArray(int size) { 354 return new ProcessStats[size]; 355 } 356 }; 357 358 public void computeTotalMemoryUse(TotalMemoryUseCollection data, long now) { 359 data.totalTime = 0; 360 for (int i=0; i<STATE_COUNT; i++) { 361 data.processStateWeight[i] = 0; 362 data.processStatePss[i] = 0; 363 data.processStateTime[i] = 0; 364 data.processStateSamples[i] = 0; 365 } 366 for (int i=0; i<SYS_MEM_USAGE_COUNT; i++) { 367 data.sysMemUsage[i] = 0; 368 } 369 data.sysMemCachedWeight = 0; 370 data.sysMemFreeWeight = 0; 371 data.sysMemZRamWeight = 0; 372 data.sysMemKernelWeight = 0; 373 data.sysMemNativeWeight = 0; 374 data.sysMemSamples = 0; 375 final long[] totalMemUsage = mSysMemUsage.getTotalMemUsage(); 376 for (int is=0; is<data.screenStates.length; is++) { 377 for (int im=0; im<data.memStates.length; im++) { 378 int memBucket = data.screenStates[is] + data.memStates[im]; 379 int stateBucket = memBucket * STATE_COUNT; 380 long memTime = mMemFactorDurations[memBucket]; 381 if (mMemFactor == memBucket) { 382 memTime += now - mStartTime; 383 } 384 data.totalTime += memTime; 385 final int sysKey = mSysMemUsage.getKey((byte)stateBucket); 386 long[] longs = totalMemUsage; 387 int idx = 0; 388 if (sysKey != SparseMappingTable.INVALID_KEY) { 389 final long[] tmpLongs = mSysMemUsage.getArrayForKey(sysKey); 390 final int tmpIndex = SparseMappingTable.getIndexFromKey(sysKey); 391 if (tmpLongs[tmpIndex+SYS_MEM_USAGE_SAMPLE_COUNT] >= 3) { 392 SysMemUsageTable.mergeSysMemUsage(data.sysMemUsage, 0, longs, idx); 393 longs = tmpLongs; 394 idx = tmpIndex; 395 } 396 } 397 data.sysMemCachedWeight += longs[idx+SYS_MEM_USAGE_CACHED_AVERAGE] 398 * (double)memTime; 399 data.sysMemFreeWeight += longs[idx+SYS_MEM_USAGE_FREE_AVERAGE] 400 * (double)memTime; 401 data.sysMemZRamWeight += longs[idx + SYS_MEM_USAGE_ZRAM_AVERAGE] 402 * (double) memTime; 403 data.sysMemKernelWeight += longs[idx+SYS_MEM_USAGE_KERNEL_AVERAGE] 404 * (double)memTime; 405 data.sysMemNativeWeight += longs[idx+SYS_MEM_USAGE_NATIVE_AVERAGE] 406 * (double)memTime; 407 data.sysMemSamples += longs[idx+SYS_MEM_USAGE_SAMPLE_COUNT]; 408 } 409 } 410 data.hasSwappedOutPss = mHasSwappedOutPss; 411 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 412 for (int iproc=0; iproc<procMap.size(); iproc++) { 413 SparseArray<ProcessState> uids = procMap.valueAt(iproc); 414 for (int iu=0; iu<uids.size(); iu++) { 415 final ProcessState proc = uids.valueAt(iu); 416 proc.aggregatePss(data, now); 417 } 418 } 419 } 420 421 public void reset() { 422 if (DEBUG) Slog.d(TAG, "Resetting state of " + mTimePeriodStartClockStr); 423 resetCommon(); 424 mPackages.getMap().clear(); 425 mProcesses.getMap().clear(); 426 mMemFactor = STATE_NOTHING; 427 mStartTime = 0; 428 if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr); 429 } 430 431 public void resetSafely() { 432 if (DEBUG) Slog.d(TAG, "Safely resetting state of " + mTimePeriodStartClockStr); 433 resetCommon(); 434 435 // First initialize use count of all common processes. 436 final long now = SystemClock.uptimeMillis(); 437 final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 438 for (int ip=procMap.size()-1; ip>=0; ip--) { 439 final SparseArray<ProcessState> uids = procMap.valueAt(ip); 440 for (int iu=uids.size()-1; iu>=0; iu--) { 441 uids.valueAt(iu).tmpNumInUse = 0; 442 } 443 } 444 445 // Next reset or prune all per-package processes, and for the ones that are reset 446 // track this back to the common processes. 447 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 448 mPackages.getMap(); 449 for (int ip=pkgMap.size()-1; ip>=0; ip--) { 450 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 451 for (int iu=uids.size()-1; iu>=0; iu--) { 452 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); 453 for (int iv=vpkgs.size()-1; iv>=0; iv--) { 454 final PackageState pkgState = vpkgs.valueAt(iv); 455 for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) { 456 final ProcessState ps = pkgState.mProcesses.valueAt(iproc); 457 if (ps.isInUse()) { 458 ps.resetSafely(now); 459 ps.getCommonProcess().tmpNumInUse++; 460 ps.getCommonProcess().tmpFoundSubProc = ps; 461 } else { 462 pkgState.mProcesses.valueAt(iproc).makeDead(); 463 pkgState.mProcesses.removeAt(iproc); 464 } 465 } 466 for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) { 467 final ServiceState ss = pkgState.mServices.valueAt(isvc); 468 if (ss.isInUse()) { 469 ss.resetSafely(now); 470 } else { 471 pkgState.mServices.removeAt(isvc); 472 } 473 } 474 if (pkgState.mProcesses.size() <= 0 && pkgState.mServices.size() <= 0) { 475 vpkgs.removeAt(iv); 476 } 477 } 478 if (vpkgs.size() <= 0) { 479 uids.removeAt(iu); 480 } 481 } 482 if (uids.size() <= 0) { 483 pkgMap.removeAt(ip); 484 } 485 } 486 487 // Finally prune out any common processes that are no longer in use. 488 for (int ip=procMap.size()-1; ip>=0; ip--) { 489 final SparseArray<ProcessState> uids = procMap.valueAt(ip); 490 for (int iu=uids.size()-1; iu>=0; iu--) { 491 ProcessState ps = uids.valueAt(iu); 492 if (ps.isInUse() || ps.tmpNumInUse > 0) { 493 // If this is a process for multiple packages, we could at this point 494 // be back down to one package. In that case, we want to revert back 495 // to a single shared ProcessState. We can do this by converting the 496 // current package-specific ProcessState up to the shared ProcessState, 497 // throwing away the current one we have here (because nobody else is 498 // using it). 499 if (!ps.isActive() && ps.isMultiPackage() && ps.tmpNumInUse == 1) { 500 // Here we go... 501 ps = ps.tmpFoundSubProc; 502 ps.makeStandalone(); 503 uids.setValueAt(iu, ps); 504 } else { 505 ps.resetSafely(now); 506 } 507 } else { 508 ps.makeDead(); 509 uids.removeAt(iu); 510 } 511 } 512 if (uids.size() <= 0) { 513 procMap.removeAt(ip); 514 } 515 } 516 517 mStartTime = now; 518 if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr); 519 } 520 521 private void resetCommon() { 522 mTimePeriodStartClock = System.currentTimeMillis(); 523 buildTimePeriodStartClockStr(); 524 mTimePeriodStartRealtime = mTimePeriodEndRealtime = SystemClock.elapsedRealtime(); 525 mTimePeriodStartUptime = mTimePeriodEndUptime = SystemClock.uptimeMillis(); 526 mInternalPssCount = 0; 527 mInternalPssTime = 0; 528 mExternalPssCount = 0; 529 mExternalPssTime = 0; 530 mExternalSlowPssCount = 0; 531 mExternalSlowPssTime = 0; 532 mTableData.reset(); 533 Arrays.fill(mMemFactorDurations, 0); 534 mSysMemUsage.resetTable(); 535 mStartTime = 0; 536 mReadError = null; 537 mFlags = 0; 538 evaluateSystemProperties(true); 539 updateFragmentation(); 540 } 541 542 public boolean evaluateSystemProperties(boolean update) { 543 boolean changed = false; 544 String runtime = SystemProperties.get("persist.sys.dalvik.vm.lib.2", 545 VMRuntime.getRuntime().vmLibrary()); 546 if (!Objects.equals(runtime, mRuntime)) { 547 changed = true; 548 if (update) { 549 mRuntime = runtime; 550 } 551 } 552 return changed; 553 } 554 555 private void buildTimePeriodStartClockStr() { 556 mTimePeriodStartClockStr = DateFormat.format("yyyy-MM-dd-HH-mm-ss", 557 mTimePeriodStartClock).toString(); 558 } 559 560 static final int[] BAD_TABLE = new int[0]; 561 562 563 /** 564 * Load the system's memory fragmentation info. 565 */ 566 public void updateFragmentation() { 567 // Parse /proc/pagetypeinfo and store the values. 568 BufferedReader reader = null; 569 try { 570 reader = new BufferedReader(new FileReader("/proc/pagetypeinfo")); 571 final Matcher matcher = sPageTypeRegex.matcher(""); 572 mPageTypeZones.clear(); 573 mPageTypeLabels.clear(); 574 mPageTypeSizes.clear(); 575 while (true) { 576 final String line = reader.readLine(); 577 if (line == null) { 578 break; 579 } 580 matcher.reset(line); 581 if (matcher.matches()) { 582 final Integer zone = Integer.valueOf(matcher.group(1), 10); 583 if (zone == null) { 584 continue; 585 } 586 mPageTypeZones.add(zone); 587 mPageTypeLabels.add(matcher.group(2)); 588 mPageTypeSizes.add(splitAndParseNumbers(matcher.group(3))); 589 } 590 } 591 } catch (IOException ex) { 592 mPageTypeZones.clear(); 593 mPageTypeLabels.clear(); 594 mPageTypeSizes.clear(); 595 return; 596 } finally { 597 if (reader != null) { 598 try { 599 reader.close(); 600 } catch (IOException allHopeIsLost) { 601 } 602 } 603 } 604 } 605 606 /** 607 * Split the string of digits separaed by spaces. There must be no 608 * leading or trailing spaces. The format is ensured by the regex 609 * above. 610 */ 611 private static int[] splitAndParseNumbers(String s) { 612 // These are always positive and the numbers can't be so big that we'll overflow 613 // so just do the parsing inline. 614 boolean digit = false; 615 int count = 0; 616 final int N = s.length(); 617 // Count the numbers 618 for (int i=0; i<N; i++) { 619 final char c = s.charAt(i); 620 if (c >= '0' && c <= '9') { 621 if (!digit) { 622 digit = true; 623 count++; 624 } 625 } else { 626 digit = false; 627 } 628 } 629 // Parse the numbers 630 final int[] result = new int[count]; 631 int p = 0; 632 int val = 0; 633 for (int i=0; i<N; i++) { 634 final char c = s.charAt(i); 635 if (c >= '0' && c <= '9') { 636 if (!digit) { 637 digit = true; 638 val = c - '0'; 639 } else { 640 val *= 10; 641 val += c - '0'; 642 } 643 } else { 644 if (digit) { 645 digit = false; 646 result[p++] = val; 647 } 648 } 649 } 650 if (count > 0) { 651 result[count-1] = val; 652 } 653 return result; 654 } 655 656 657 private void writeCompactedLongArray(Parcel out, long[] array, int num) { 658 for (int i=0; i<num; i++) { 659 long val = array[i]; 660 if (val < 0) { 661 Slog.w(TAG, "Time val negative: " + val); 662 val = 0; 663 } 664 if (val <= Integer.MAX_VALUE) { 665 out.writeInt((int)val); 666 } else { 667 int top = ~((int)((val>>32)&0x7fffffff)); 668 int bottom = (int)(val&0x0ffffffffL); 669 out.writeInt(top); 670 out.writeInt(bottom); 671 } 672 } 673 } 674 675 private void readCompactedLongArray(Parcel in, int version, long[] array, int num) { 676 if (version <= 10) { 677 in.readLongArray(array); 678 return; 679 } 680 final int alen = array.length; 681 if (num > alen) { 682 throw new RuntimeException("bad array lengths: got " + num + " array is " + alen); 683 } 684 int i; 685 for (i=0; i<num; i++) { 686 int val = in.readInt(); 687 if (val >= 0) { 688 array[i] = val; 689 } else { 690 int bottom = in.readInt(); 691 array[i] = (((long)~val)<<32) | bottom; 692 } 693 } 694 while (i < alen) { 695 array[i] = 0; 696 i++; 697 } 698 } 699 700 private void writeCommonString(Parcel out, String name) { 701 Integer index = mCommonStringToIndex.get(name); 702 if (index != null) { 703 out.writeInt(index); 704 return; 705 } 706 index = mCommonStringToIndex.size(); 707 mCommonStringToIndex.put(name, index); 708 out.writeInt(~index); 709 out.writeString(name); 710 } 711 712 private String readCommonString(Parcel in, int version) { 713 if (version <= 9) { 714 return in.readString(); 715 } 716 int index = in.readInt(); 717 if (index >= 0) { 718 return mIndexToCommonString.get(index); 719 } 720 index = ~index; 721 String name = in.readString(); 722 while (mIndexToCommonString.size() <= index) { 723 mIndexToCommonString.add(null); 724 } 725 mIndexToCommonString.set(index, name); 726 return name; 727 } 728 729 @Override 730 public int describeContents() { 731 return 0; 732 } 733 734 @Override 735 public void writeToParcel(Parcel out, int flags) { 736 writeToParcel(out, SystemClock.uptimeMillis(), flags); 737 } 738 739 /** @hide */ 740 public void writeToParcel(Parcel out, long now, int flags) { 741 out.writeInt(MAGIC); 742 out.writeInt(PARCEL_VERSION); 743 out.writeInt(STATE_COUNT); 744 out.writeInt(ADJ_COUNT); 745 out.writeInt(PSS_COUNT); 746 out.writeInt(SYS_MEM_USAGE_COUNT); 747 out.writeInt(SparseMappingTable.ARRAY_SIZE); 748 749 mCommonStringToIndex = new ArrayMap<String, Integer>(mProcesses.size()); 750 751 // First commit all running times. 752 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 753 final int NPROC = procMap.size(); 754 for (int ip=0; ip<NPROC; ip++) { 755 SparseArray<ProcessState> uids = procMap.valueAt(ip); 756 final int NUID = uids.size(); 757 for (int iu=0; iu<NUID; iu++) { 758 uids.valueAt(iu).commitStateTime(now); 759 } 760 } 761 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 762 mPackages.getMap(); 763 final int NPKG = pkgMap.size(); 764 for (int ip=0; ip<NPKG; ip++) { 765 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 766 final int NUID = uids.size(); 767 for (int iu=0; iu<NUID; iu++) { 768 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); 769 final int NVERS = vpkgs.size(); 770 for (int iv=0; iv<NVERS; iv++) { 771 PackageState pkgState = vpkgs.valueAt(iv); 772 final int NPROCS = pkgState.mProcesses.size(); 773 for (int iproc=0; iproc<NPROCS; iproc++) { 774 ProcessState proc = pkgState.mProcesses.valueAt(iproc); 775 if (proc.getCommonProcess() != proc) { 776 proc.commitStateTime(now); 777 } 778 } 779 final int NSRVS = pkgState.mServices.size(); 780 for (int isvc=0; isvc<NSRVS; isvc++) { 781 pkgState.mServices.valueAt(isvc).commitStateTime(now); 782 } 783 } 784 } 785 } 786 787 out.writeLong(mTimePeriodStartClock); 788 out.writeLong(mTimePeriodStartRealtime); 789 out.writeLong(mTimePeriodEndRealtime); 790 out.writeLong(mTimePeriodStartUptime); 791 out.writeLong(mTimePeriodEndUptime); 792 out.writeLong(mInternalPssCount); 793 out.writeLong(mInternalPssTime); 794 out.writeLong(mExternalPssCount); 795 out.writeLong(mExternalPssTime); 796 out.writeLong(mExternalSlowPssCount); 797 out.writeLong(mExternalSlowPssTime); 798 out.writeString(mRuntime); 799 out.writeInt(mHasSwappedOutPss ? 1 : 0); 800 out.writeInt(mFlags); 801 802 mTableData.writeToParcel(out); 803 804 if (mMemFactor != STATE_NOTHING) { 805 mMemFactorDurations[mMemFactor] += now - mStartTime; 806 mStartTime = now; 807 } 808 writeCompactedLongArray(out, mMemFactorDurations, mMemFactorDurations.length); 809 810 mSysMemUsage.writeToParcel(out); 811 812 out.writeInt(NPROC); 813 for (int ip=0; ip<NPROC; ip++) { 814 writeCommonString(out, procMap.keyAt(ip)); 815 final SparseArray<ProcessState> uids = procMap.valueAt(ip); 816 final int NUID = uids.size(); 817 out.writeInt(NUID); 818 for (int iu=0; iu<NUID; iu++) { 819 out.writeInt(uids.keyAt(iu)); 820 final ProcessState proc = uids.valueAt(iu); 821 writeCommonString(out, proc.getPackage()); 822 out.writeLong(proc.getVersion()); 823 proc.writeToParcel(out, now); 824 } 825 } 826 out.writeInt(NPKG); 827 for (int ip=0; ip<NPKG; ip++) { 828 writeCommonString(out, pkgMap.keyAt(ip)); 829 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 830 final int NUID = uids.size(); 831 out.writeInt(NUID); 832 for (int iu=0; iu<NUID; iu++) { 833 out.writeInt(uids.keyAt(iu)); 834 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); 835 final int NVERS = vpkgs.size(); 836 out.writeInt(NVERS); 837 for (int iv=0; iv<NVERS; iv++) { 838 out.writeLong(vpkgs.keyAt(iv)); 839 final PackageState pkgState = vpkgs.valueAt(iv); 840 final int NPROCS = pkgState.mProcesses.size(); 841 out.writeInt(NPROCS); 842 for (int iproc=0; iproc<NPROCS; iproc++) { 843 writeCommonString(out, pkgState.mProcesses.keyAt(iproc)); 844 final ProcessState proc = pkgState.mProcesses.valueAt(iproc); 845 if (proc.getCommonProcess() == proc) { 846 // This is the same as the common process we wrote above. 847 out.writeInt(0); 848 } else { 849 // There is separate data for this package's process. 850 out.writeInt(1); 851 proc.writeToParcel(out, now); 852 } 853 } 854 final int NSRVS = pkgState.mServices.size(); 855 out.writeInt(NSRVS); 856 for (int isvc=0; isvc<NSRVS; isvc++) { 857 out.writeString(pkgState.mServices.keyAt(isvc)); 858 final ServiceState svc = pkgState.mServices.valueAt(isvc); 859 writeCommonString(out, svc.getProcessName()); 860 svc.writeToParcel(out, now); 861 } 862 } 863 } 864 } 865 866 // Fragmentation info (/proc/pagetypeinfo) 867 final int NPAGETYPES = mPageTypeLabels.size(); 868 out.writeInt(NPAGETYPES); 869 for (int i=0; i<NPAGETYPES; i++) { 870 out.writeInt(mPageTypeZones.get(i)); 871 out.writeString(mPageTypeLabels.get(i)); 872 out.writeIntArray(mPageTypeSizes.get(i)); 873 } 874 875 mCommonStringToIndex = null; 876 } 877 878 private boolean readCheckedInt(Parcel in, int val, String what) { 879 int got; 880 if ((got=in.readInt()) != val) { 881 mReadError = "bad " + what + ": " + got; 882 return false; 883 } 884 return true; 885 } 886 887 static byte[] readFully(InputStream stream, int[] outLen) throws IOException { 888 int pos = 0; 889 final int initialAvail = stream.available(); 890 byte[] data = new byte[initialAvail > 0 ? (initialAvail+1) : 16384]; 891 while (true) { 892 int amt = stream.read(data, pos, data.length-pos); 893 if (DEBUG_PARCEL) Slog.i("foo", "Read " + amt + " bytes at " + pos 894 + " of avail " + data.length); 895 if (amt < 0) { 896 if (DEBUG_PARCEL) Slog.i("foo", "**** FINISHED READING: pos=" + pos 897 + " len=" + data.length); 898 outLen[0] = pos; 899 return data; 900 } 901 pos += amt; 902 if (pos >= data.length) { 903 byte[] newData = new byte[pos+16384]; 904 if (DEBUG_PARCEL) Slog.i(TAG, "Copying " + pos + " bytes to new array len " 905 + newData.length); 906 System.arraycopy(data, 0, newData, 0, pos); 907 data = newData; 908 } 909 } 910 } 911 912 public void read(InputStream stream) { 913 try { 914 int[] len = new int[1]; 915 byte[] raw = readFully(stream, len); 916 Parcel in = Parcel.obtain(); 917 in.unmarshall(raw, 0, len[0]); 918 in.setDataPosition(0); 919 stream.close(); 920 921 readFromParcel(in); 922 } catch (IOException e) { 923 mReadError = "caught exception: " + e; 924 } 925 } 926 927 public void readFromParcel(Parcel in) { 928 final boolean hadData = mPackages.getMap().size() > 0 929 || mProcesses.getMap().size() > 0; 930 if (hadData) { 931 resetSafely(); 932 } 933 934 if (!readCheckedInt(in, MAGIC, "magic number")) { 935 return; 936 } 937 int version = in.readInt(); 938 if (version != PARCEL_VERSION) { 939 mReadError = "bad version: " + version; 940 return; 941 } 942 if (!readCheckedInt(in, STATE_COUNT, "state count")) { 943 return; 944 } 945 if (!readCheckedInt(in, ADJ_COUNT, "adj count")) { 946 return; 947 } 948 if (!readCheckedInt(in, PSS_COUNT, "pss count")) { 949 return; 950 } 951 if (!readCheckedInt(in, SYS_MEM_USAGE_COUNT, "sys mem usage count")) { 952 return; 953 } 954 if (!readCheckedInt(in, SparseMappingTable.ARRAY_SIZE, "longs size")) { 955 return; 956 } 957 958 mIndexToCommonString = new ArrayList<String>(); 959 960 mTimePeriodStartClock = in.readLong(); 961 buildTimePeriodStartClockStr(); 962 mTimePeriodStartRealtime = in.readLong(); 963 mTimePeriodEndRealtime = in.readLong(); 964 mTimePeriodStartUptime = in.readLong(); 965 mTimePeriodEndUptime = in.readLong(); 966 mInternalPssCount = in.readLong(); 967 mInternalPssTime = in.readLong(); 968 mExternalPssCount = in.readLong(); 969 mExternalPssTime = in.readLong(); 970 mExternalSlowPssCount = in.readLong(); 971 mExternalSlowPssTime = in.readLong(); 972 mRuntime = in.readString(); 973 mHasSwappedOutPss = in.readInt() != 0; 974 mFlags = in.readInt(); 975 mTableData.readFromParcel(in); 976 readCompactedLongArray(in, version, mMemFactorDurations, mMemFactorDurations.length); 977 if (!mSysMemUsage.readFromParcel(in)) { 978 return; 979 } 980 981 int NPROC = in.readInt(); 982 if (NPROC < 0) { 983 mReadError = "bad process count: " + NPROC; 984 return; 985 } 986 while (NPROC > 0) { 987 NPROC--; 988 final String procName = readCommonString(in, version); 989 if (procName == null) { 990 mReadError = "bad process name"; 991 return; 992 } 993 int NUID = in.readInt(); 994 if (NUID < 0) { 995 mReadError = "bad uid count: " + NUID; 996 return; 997 } 998 while (NUID > 0) { 999 NUID--; 1000 final int uid = in.readInt(); 1001 if (uid < 0) { 1002 mReadError = "bad uid: " + uid; 1003 return; 1004 } 1005 final String pkgName = readCommonString(in, version); 1006 if (pkgName == null) { 1007 mReadError = "bad process package name"; 1008 return; 1009 } 1010 final long vers = in.readLong(); 1011 ProcessState proc = hadData ? mProcesses.get(procName, uid) : null; 1012 if (proc != null) { 1013 if (!proc.readFromParcel(in, false)) { 1014 return; 1015 } 1016 } else { 1017 proc = new ProcessState(this, pkgName, uid, vers, procName); 1018 if (!proc.readFromParcel(in, true)) { 1019 return; 1020 } 1021 } 1022 if (DEBUG_PARCEL) Slog.d(TAG, "Adding process: " + procName + " " + uid 1023 + " " + proc); 1024 mProcesses.put(procName, uid, proc); 1025 } 1026 } 1027 1028 if (DEBUG_PARCEL) Slog.d(TAG, "Read " + mProcesses.getMap().size() + " processes"); 1029 1030 int NPKG = in.readInt(); 1031 if (NPKG < 0) { 1032 mReadError = "bad package count: " + NPKG; 1033 return; 1034 } 1035 while (NPKG > 0) { 1036 NPKG--; 1037 final String pkgName = readCommonString(in, version); 1038 if (pkgName == null) { 1039 mReadError = "bad package name"; 1040 return; 1041 } 1042 int NUID = in.readInt(); 1043 if (NUID < 0) { 1044 mReadError = "bad uid count: " + NUID; 1045 return; 1046 } 1047 while (NUID > 0) { 1048 NUID--; 1049 final int uid = in.readInt(); 1050 if (uid < 0) { 1051 mReadError = "bad uid: " + uid; 1052 return; 1053 } 1054 int NVERS = in.readInt(); 1055 if (NVERS < 0) { 1056 mReadError = "bad versions count: " + NVERS; 1057 return; 1058 } 1059 while (NVERS > 0) { 1060 NVERS--; 1061 final long vers = in.readLong(); 1062 PackageState pkgState = new PackageState(pkgName, uid); 1063 LongSparseArray<PackageState> vpkg = mPackages.get(pkgName, uid); 1064 if (vpkg == null) { 1065 vpkg = new LongSparseArray<>(); 1066 mPackages.put(pkgName, uid, vpkg); 1067 } 1068 vpkg.put(vers, pkgState); 1069 int NPROCS = in.readInt(); 1070 if (NPROCS < 0) { 1071 mReadError = "bad package process count: " + NPROCS; 1072 return; 1073 } 1074 while (NPROCS > 0) { 1075 NPROCS--; 1076 String procName = readCommonString(in, version); 1077 if (procName == null) { 1078 mReadError = "bad package process name"; 1079 return; 1080 } 1081 int hasProc = in.readInt(); 1082 if (DEBUG_PARCEL) Slog.d(TAG, "Reading package " + pkgName + " " + uid 1083 + " process " + procName + " hasProc=" + hasProc); 1084 ProcessState commonProc = mProcesses.get(procName, uid); 1085 if (DEBUG_PARCEL) Slog.d(TAG, "Got common proc " + procName + " " + uid 1086 + ": " + commonProc); 1087 if (commonProc == null) { 1088 mReadError = "no common proc: " + procName; 1089 return; 1090 } 1091 if (hasProc != 0) { 1092 // The process for this package is unique to the package; we 1093 // need to load it. We don't need to do anything about it if 1094 // it is not unique because if someone later looks for it 1095 // they will find and use it from the global procs. 1096 ProcessState proc = hadData ? pkgState.mProcesses.get(procName) : null; 1097 if (proc != null) { 1098 if (!proc.readFromParcel(in, false)) { 1099 return; 1100 } 1101 } else { 1102 proc = new ProcessState(commonProc, pkgName, uid, vers, procName, 1103 0); 1104 if (!proc.readFromParcel(in, true)) { 1105 return; 1106 } 1107 } 1108 if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: " 1109 + procName + " " + uid + " " + proc); 1110 pkgState.mProcesses.put(procName, proc); 1111 } else { 1112 if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: " 1113 + procName + " " + uid + " " + commonProc); 1114 pkgState.mProcesses.put(procName, commonProc); 1115 } 1116 } 1117 int NSRVS = in.readInt(); 1118 if (NSRVS < 0) { 1119 mReadError = "bad package service count: " + NSRVS; 1120 return; 1121 } 1122 while (NSRVS > 0) { 1123 NSRVS--; 1124 String serviceName = in.readString(); 1125 if (serviceName == null) { 1126 mReadError = "bad package service name"; 1127 return; 1128 } 1129 String processName = version > 9 ? readCommonString(in, version) : null; 1130 ServiceState serv = hadData ? pkgState.mServices.get(serviceName) : null; 1131 if (serv == null) { 1132 serv = new ServiceState(this, pkgName, serviceName, processName, null); 1133 } 1134 if (!serv.readFromParcel(in)) { 1135 return; 1136 } 1137 if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " service: " 1138 + serviceName + " " + uid + " " + serv); 1139 pkgState.mServices.put(serviceName, serv); 1140 } 1141 } 1142 } 1143 } 1144 1145 // Fragmentation info 1146 final int NPAGETYPES = in.readInt(); 1147 mPageTypeZones.clear(); 1148 mPageTypeZones.ensureCapacity(NPAGETYPES); 1149 mPageTypeLabels.clear(); 1150 mPageTypeLabels.ensureCapacity(NPAGETYPES); 1151 mPageTypeSizes.clear(); 1152 mPageTypeSizes.ensureCapacity(NPAGETYPES); 1153 for (int i=0; i<NPAGETYPES; i++) { 1154 mPageTypeZones.add(in.readInt()); 1155 mPageTypeLabels.add(in.readString()); 1156 mPageTypeSizes.add(in.createIntArray()); 1157 } 1158 1159 mIndexToCommonString = null; 1160 1161 if (DEBUG_PARCEL) Slog.d(TAG, "Successfully read procstats!"); 1162 } 1163 1164 public PackageState getPackageStateLocked(String packageName, int uid, long vers) { 1165 LongSparseArray<PackageState> vpkg = mPackages.get(packageName, uid); 1166 if (vpkg == null) { 1167 vpkg = new LongSparseArray<PackageState>(); 1168 mPackages.put(packageName, uid, vpkg); 1169 } 1170 PackageState as = vpkg.get(vers); 1171 if (as != null) { 1172 return as; 1173 } 1174 as = new PackageState(packageName, uid); 1175 vpkg.put(vers, as); 1176 return as; 1177 } 1178 1179 public ProcessState getProcessStateLocked(String packageName, int uid, long vers, 1180 String processName) { 1181 final PackageState pkgState = getPackageStateLocked(packageName, uid, vers); 1182 ProcessState ps = pkgState.mProcesses.get(processName); 1183 if (ps != null) { 1184 return ps; 1185 } 1186 ProcessState commonProc = mProcesses.get(processName, uid); 1187 if (commonProc == null) { 1188 commonProc = new ProcessState(this, packageName, uid, vers, processName); 1189 mProcesses.put(processName, uid, commonProc); 1190 if (DEBUG) Slog.d(TAG, "GETPROC created new common " + commonProc); 1191 } 1192 if (!commonProc.isMultiPackage()) { 1193 if (packageName.equals(commonProc.getPackage()) && vers == commonProc.getVersion()) { 1194 // This common process is not in use by multiple packages, and 1195 // is for the calling package, so we can just use it directly. 1196 ps = commonProc; 1197 if (DEBUG) Slog.d(TAG, "GETPROC also using for pkg " + commonProc); 1198 } else { 1199 if (DEBUG) Slog.d(TAG, "GETPROC need to split common proc!"); 1200 // This common process has not been in use by multiple packages, 1201 // but it was created for a different package than the caller. 1202 // We need to convert it to a multi-package process. 1203 commonProc.setMultiPackage(true); 1204 // To do this, we need to make two new process states, one a copy 1205 // of the current state for the process under the original package 1206 // name, and the second a free new process state for it as the 1207 // new package name. 1208 long now = SystemClock.uptimeMillis(); 1209 // First let's make a copy of the current process state and put 1210 // that under the now unique state for its original package name. 1211 final PackageState commonPkgState = getPackageStateLocked(commonProc.getPackage(), 1212 uid, commonProc.getVersion()); 1213 if (commonPkgState != null) { 1214 ProcessState cloned = commonProc.clone(now); 1215 if (DEBUG) Slog.d(TAG, "GETPROC setting clone to pkg " + commonProc.getPackage() 1216 + ": " + cloned); 1217 commonPkgState.mProcesses.put(commonProc.getName(), cloned); 1218 // If this has active services, we need to update their process pointer 1219 // to point to the new package-specific process state. 1220 for (int i=commonPkgState.mServices.size()-1; i>=0; i--) { 1221 ServiceState ss = commonPkgState.mServices.valueAt(i); 1222 if (ss.getProcess() == commonProc) { 1223 if (DEBUG) Slog.d(TAG, "GETPROC switching service to cloned: " + ss); 1224 ss.setProcess(cloned); 1225 } else if (DEBUG) { 1226 Slog.d(TAG, "GETPROC leaving proc of " + ss); 1227 } 1228 } 1229 } else { 1230 Slog.w(TAG, "Cloning proc state: no package state " + commonProc.getPackage() 1231 + "/" + uid + " for proc " + commonProc.getName()); 1232 } 1233 // And now make a fresh new process state for the new package name. 1234 ps = new ProcessState(commonProc, packageName, uid, vers, processName, now); 1235 if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps); 1236 } 1237 } else { 1238 // The common process is for multiple packages, we need to create a 1239 // separate object for the per-package data. 1240 ps = new ProcessState(commonProc, packageName, uid, vers, processName, 1241 SystemClock.uptimeMillis()); 1242 if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps); 1243 } 1244 pkgState.mProcesses.put(processName, ps); 1245 if (DEBUG) Slog.d(TAG, "GETPROC adding new pkg " + ps); 1246 return ps; 1247 } 1248 1249 public ServiceState getServiceStateLocked(String packageName, int uid, long vers, 1250 String processName, String className) { 1251 final ProcessStats.PackageState as = getPackageStateLocked(packageName, uid, vers); 1252 ServiceState ss = as.mServices.get(className); 1253 if (ss != null) { 1254 if (DEBUG) Slog.d(TAG, "GETSVC: returning existing " + ss); 1255 return ss; 1256 } 1257 final ProcessState ps = processName != null 1258 ? getProcessStateLocked(packageName, uid, vers, processName) : null; 1259 ss = new ServiceState(this, packageName, className, processName, ps); 1260 as.mServices.put(className, ss); 1261 if (DEBUG) Slog.d(TAG, "GETSVC: creating " + ss + " in " + ps); 1262 return ss; 1263 } 1264 1265 public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary, 1266 boolean dumpAll, boolean activeOnly) { 1267 long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor, 1268 mStartTime, now); 1269 boolean sepNeeded = false; 1270 if (mSysMemUsage.getKeyCount() > 0) { 1271 pw.println("System memory usage:"); 1272 mSysMemUsage.dump(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ); 1273 sepNeeded = true; 1274 } 1275 ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = mPackages.getMap(); 1276 boolean printedHeader = false; 1277 for (int ip=0; ip<pkgMap.size(); ip++) { 1278 final String pkgName = pkgMap.keyAt(ip); 1279 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 1280 for (int iu=0; iu<uids.size(); iu++) { 1281 final int uid = uids.keyAt(iu); 1282 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); 1283 for (int iv=0; iv<vpkgs.size(); iv++) { 1284 final long vers = vpkgs.keyAt(iv); 1285 final PackageState pkgState = vpkgs.valueAt(iv); 1286 final int NPROCS = pkgState.mProcesses.size(); 1287 final int NSRVS = pkgState.mServices.size(); 1288 final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName); 1289 if (!pkgMatch) { 1290 boolean procMatch = false; 1291 for (int iproc=0; iproc<NPROCS; iproc++) { 1292 ProcessState proc = pkgState.mProcesses.valueAt(iproc); 1293 if (reqPackage.equals(proc.getName())) { 1294 procMatch = true; 1295 break; 1296 } 1297 } 1298 if (!procMatch) { 1299 continue; 1300 } 1301 } 1302 if (NPROCS > 0 || NSRVS > 0) { 1303 if (!printedHeader) { 1304 if (sepNeeded) pw.println(); 1305 pw.println("Per-Package Stats:"); 1306 printedHeader = true; 1307 sepNeeded = true; 1308 } 1309 pw.print(" * "); pw.print(pkgName); pw.print(" / "); 1310 UserHandle.formatUid(pw, uid); pw.print(" / v"); 1311 pw.print(vers); pw.println(":"); 1312 } 1313 if (!dumpSummary || dumpAll) { 1314 for (int iproc=0; iproc<NPROCS; iproc++) { 1315 ProcessState proc = pkgState.mProcesses.valueAt(iproc); 1316 if (!pkgMatch && !reqPackage.equals(proc.getName())) { 1317 continue; 1318 } 1319 if (activeOnly && !proc.isInUse()) { 1320 pw.print(" (Not active: "); 1321 pw.print(pkgState.mProcesses.keyAt(iproc)); pw.println(")"); 1322 continue; 1323 } 1324 pw.print(" Process "); 1325 pw.print(pkgState.mProcesses.keyAt(iproc)); 1326 if (proc.getCommonProcess().isMultiPackage()) { 1327 pw.print(" (multi, "); 1328 } else { 1329 pw.print(" (unique, "); 1330 } 1331 pw.print(proc.getDurationsBucketCount()); 1332 pw.print(" entries)"); 1333 pw.println(":"); 1334 proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, 1335 ALL_PROC_STATES, now); 1336 proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, 1337 ALL_PROC_STATES); 1338 proc.dumpInternalLocked(pw, " ", dumpAll); 1339 } 1340 } else { 1341 ArrayList<ProcessState> procs = new ArrayList<ProcessState>(); 1342 for (int iproc=0; iproc<NPROCS; iproc++) { 1343 ProcessState proc = pkgState.mProcesses.valueAt(iproc); 1344 if (!pkgMatch && !reqPackage.equals(proc.getName())) { 1345 continue; 1346 } 1347 if (activeOnly && !proc.isInUse()) { 1348 continue; 1349 } 1350 procs.add(proc); 1351 } 1352 DumpUtils.dumpProcessSummaryLocked(pw, " ", procs, 1353 ALL_SCREEN_ADJ, ALL_MEM_ADJ, NON_CACHED_PROC_STATES, 1354 now, totalTime); 1355 } 1356 for (int isvc=0; isvc<NSRVS; isvc++) { 1357 ServiceState svc = pkgState.mServices.valueAt(isvc); 1358 if (!pkgMatch && !reqPackage.equals(svc.getProcessName())) { 1359 continue; 1360 } 1361 if (activeOnly && !svc.isInUse()) { 1362 pw.print(" (Not active: "); 1363 pw.print(pkgState.mServices.keyAt(isvc)); pw.println(")"); 1364 continue; 1365 } 1366 if (dumpAll) { 1367 pw.print(" Service "); 1368 } else { 1369 pw.print(" * "); 1370 } 1371 pw.print(pkgState.mServices.keyAt(isvc)); 1372 pw.println(":"); 1373 pw.print(" Process: "); pw.println(svc.getProcessName()); 1374 svc.dumpStats(pw, " ", " ", " ", 1375 now, totalTime, dumpSummary, dumpAll); 1376 } 1377 } 1378 } 1379 } 1380 1381 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 1382 printedHeader = false; 1383 int numShownProcs = 0, numTotalProcs = 0; 1384 for (int ip=0; ip<procMap.size(); ip++) { 1385 String procName = procMap.keyAt(ip); 1386 SparseArray<ProcessState> uids = procMap.valueAt(ip); 1387 for (int iu=0; iu<uids.size(); iu++) { 1388 int uid = uids.keyAt(iu); 1389 numTotalProcs++; 1390 final ProcessState proc = uids.valueAt(iu); 1391 if (proc.hasAnyData()) { 1392 continue; 1393 } 1394 if (!proc.isMultiPackage()) { 1395 continue; 1396 } 1397 if (reqPackage != null && !reqPackage.equals(procName) 1398 && !reqPackage.equals(proc.getPackage())) { 1399 continue; 1400 } 1401 numShownProcs++; 1402 if (sepNeeded) { 1403 pw.println(); 1404 } 1405 sepNeeded = true; 1406 if (!printedHeader) { 1407 pw.println("Multi-Package Common Processes:"); 1408 printedHeader = true; 1409 } 1410 if (activeOnly && !proc.isInUse()) { 1411 pw.print(" (Not active: "); pw.print(procName); pw.println(")"); 1412 continue; 1413 } 1414 pw.print(" * "); pw.print(procName); pw.print(" / "); 1415 UserHandle.formatUid(pw, uid); 1416 pw.print(" ("); pw.print(proc.getDurationsBucketCount()); 1417 pw.print(" entries)"); pw.println(":"); 1418 proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, 1419 ALL_PROC_STATES, now); 1420 proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES); 1421 proc.dumpInternalLocked(pw, " ", dumpAll); 1422 } 1423 } 1424 if (dumpAll) { 1425 pw.println(); 1426 pw.print(" Total procs: "); pw.print(numShownProcs); 1427 pw.print(" shown of "); pw.print(numTotalProcs); pw.println(" total"); 1428 } 1429 1430 if (sepNeeded) { 1431 pw.println(); 1432 } 1433 if (dumpSummary) { 1434 pw.println("Summary:"); 1435 dumpSummaryLocked(pw, reqPackage, now, activeOnly); 1436 } else { 1437 dumpTotalsLocked(pw, now); 1438 } 1439 1440 if (dumpAll) { 1441 pw.println(); 1442 pw.println("Internal state:"); 1443 /* 1444 pw.print(" Num long arrays: "); pw.println(mLongs.size()); 1445 pw.print(" Next long entry: "); pw.println(mNextLong); 1446 */ 1447 pw.print(" mRunning="); pw.println(mRunning); 1448 } 1449 1450 dumpFragmentationLocked(pw); 1451 } 1452 1453 public void dumpSummaryLocked(PrintWriter pw, String reqPackage, long now, boolean activeOnly) { 1454 long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor, 1455 mStartTime, now); 1456 dumpFilteredSummaryLocked(pw, null, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, 1457 ALL_PROC_STATES, NON_CACHED_PROC_STATES, now, totalTime, reqPackage, activeOnly); 1458 pw.println(); 1459 dumpTotalsLocked(pw, now); 1460 } 1461 1462 private void dumpFragmentationLocked(PrintWriter pw) { 1463 pw.println(); 1464 pw.println("Available pages by page size:"); 1465 final int NPAGETYPES = mPageTypeLabels.size(); 1466 for (int i=0; i<NPAGETYPES; i++) { 1467 pw.format("Zone %3d %14s ", mPageTypeZones.get(i), mPageTypeLabels.get(i)); 1468 final int[] sizes = mPageTypeSizes.get(i); 1469 final int N = sizes == null ? 0 : sizes.length; 1470 for (int j=0; j<N; j++) { 1471 pw.format("%6d", sizes[j]); 1472 } 1473 pw.println(); 1474 } 1475 } 1476 1477 long printMemoryCategory(PrintWriter pw, String prefix, String label, double memWeight, 1478 long totalTime, long curTotalMem, int samples) { 1479 if (memWeight != 0) { 1480 long mem = (long)(memWeight * 1024 / totalTime); 1481 pw.print(prefix); 1482 pw.print(label); 1483 pw.print(": "); 1484 DebugUtils.printSizeValue(pw, mem); 1485 pw.print(" ("); 1486 pw.print(samples); 1487 pw.print(" samples)"); 1488 pw.println(); 1489 return curTotalMem + mem; 1490 } 1491 return curTotalMem; 1492 } 1493 1494 void dumpTotalsLocked(PrintWriter pw, long now) { 1495 pw.println("Run time Stats:"); 1496 DumpUtils.dumpSingleTime(pw, " ", mMemFactorDurations, mMemFactor, mStartTime, now); 1497 pw.println(); 1498 pw.println("Memory usage:"); 1499 TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ, 1500 ALL_MEM_ADJ); 1501 computeTotalMemoryUse(totalMem, now); 1502 long totalPss = 0; 1503 totalPss = printMemoryCategory(pw, " ", "Kernel ", totalMem.sysMemKernelWeight, 1504 totalMem.totalTime, totalPss, totalMem.sysMemSamples); 1505 totalPss = printMemoryCategory(pw, " ", "Native ", totalMem.sysMemNativeWeight, 1506 totalMem.totalTime, totalPss, totalMem.sysMemSamples); 1507 for (int i=0; i<STATE_COUNT; i++) { 1508 // Skip restarting service state -- that is not actually a running process. 1509 if (i != STATE_SERVICE_RESTARTING) { 1510 totalPss = printMemoryCategory(pw, " ", DumpUtils.STATE_NAMES[i], 1511 totalMem.processStateWeight[i], totalMem.totalTime, totalPss, 1512 totalMem.processStateSamples[i]); 1513 } 1514 } 1515 totalPss = printMemoryCategory(pw, " ", "Cached ", totalMem.sysMemCachedWeight, 1516 totalMem.totalTime, totalPss, totalMem.sysMemSamples); 1517 totalPss = printMemoryCategory(pw, " ", "Free ", totalMem.sysMemFreeWeight, 1518 totalMem.totalTime, totalPss, totalMem.sysMemSamples); 1519 totalPss = printMemoryCategory(pw, " ", "Z-Ram ", totalMem.sysMemZRamWeight, 1520 totalMem.totalTime, totalPss, totalMem.sysMemSamples); 1521 pw.print(" TOTAL : "); 1522 DebugUtils.printSizeValue(pw, totalPss); 1523 pw.println(); 1524 printMemoryCategory(pw, " ", DumpUtils.STATE_NAMES[STATE_SERVICE_RESTARTING], 1525 totalMem.processStateWeight[STATE_SERVICE_RESTARTING], totalMem.totalTime, totalPss, 1526 totalMem.processStateSamples[STATE_SERVICE_RESTARTING]); 1527 pw.println(); 1528 pw.println("PSS collection stats:"); 1529 pw.print(" Internal: "); 1530 pw.print(mInternalPssCount); 1531 pw.print("x over "); 1532 TimeUtils.formatDuration(mInternalPssTime, pw); 1533 pw.println(); 1534 pw.print(" External: "); 1535 pw.print(mExternalPssCount); 1536 pw.print("x over "); 1537 TimeUtils.formatDuration(mExternalPssTime, pw); 1538 pw.println(); 1539 pw.print(" External Slow: "); 1540 pw.print(mExternalSlowPssCount); 1541 pw.print("x over "); 1542 TimeUtils.formatDuration(mExternalSlowPssTime, pw); 1543 pw.println(); 1544 pw.println(); 1545 pw.print(" Start time: "); 1546 pw.print(DateFormat.format("yyyy-MM-dd HH:mm:ss", mTimePeriodStartClock)); 1547 pw.println(); 1548 pw.print(" Total uptime: "); 1549 TimeUtils.formatDuration( 1550 (mRunning ? SystemClock.uptimeMillis() : mTimePeriodEndUptime) 1551 - mTimePeriodStartUptime, pw); 1552 pw.println(); 1553 pw.print(" Total elapsed time: "); 1554 TimeUtils.formatDuration( 1555 (mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime) 1556 - mTimePeriodStartRealtime, pw); 1557 boolean partial = true; 1558 if ((mFlags&FLAG_SHUTDOWN) != 0) { 1559 pw.print(" (shutdown)"); 1560 partial = false; 1561 } 1562 if ((mFlags&FLAG_SYSPROPS) != 0) { 1563 pw.print(" (sysprops)"); 1564 partial = false; 1565 } 1566 if ((mFlags&FLAG_COMPLETE) != 0) { 1567 pw.print(" (complete)"); 1568 partial = false; 1569 } 1570 if (partial) { 1571 pw.print(" (partial)"); 1572 } 1573 if (mHasSwappedOutPss) { 1574 pw.print(" (swapped-out-pss)"); 1575 } 1576 pw.print(' '); 1577 pw.print(mRuntime); 1578 pw.println(); 1579 } 1580 1581 void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix, 1582 int[] screenStates, int[] memStates, int[] procStates, 1583 int[] sortProcStates, long now, long totalTime, String reqPackage, boolean activeOnly) { 1584 ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates, 1585 procStates, sortProcStates, now, reqPackage, activeOnly); 1586 if (procs.size() > 0) { 1587 if (header != null) { 1588 pw.println(); 1589 pw.println(header); 1590 } 1591 DumpUtils.dumpProcessSummaryLocked(pw, prefix, procs, screenStates, memStates, 1592 sortProcStates, now, totalTime); 1593 } 1594 } 1595 1596 public ArrayList<ProcessState> collectProcessesLocked(int[] screenStates, int[] memStates, 1597 int[] procStates, int sortProcStates[], long now, String reqPackage, 1598 boolean activeOnly) { 1599 final ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>(); 1600 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 1601 mPackages.getMap(); 1602 for (int ip=0; ip<pkgMap.size(); ip++) { 1603 final String pkgName = pkgMap.keyAt(ip); 1604 final SparseArray<LongSparseArray<PackageState>> procs = pkgMap.valueAt(ip); 1605 for (int iu=0; iu<procs.size(); iu++) { 1606 final LongSparseArray<PackageState> vpkgs = procs.valueAt(iu); 1607 final int NVERS = vpkgs.size(); 1608 for (int iv=0; iv<NVERS; iv++) { 1609 final PackageState state = vpkgs.valueAt(iv); 1610 final int NPROCS = state.mProcesses.size(); 1611 final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName); 1612 for (int iproc=0; iproc<NPROCS; iproc++) { 1613 final ProcessState proc = state.mProcesses.valueAt(iproc); 1614 if (!pkgMatch && !reqPackage.equals(proc.getName())) { 1615 continue; 1616 } 1617 if (activeOnly && !proc.isInUse()) { 1618 continue; 1619 } 1620 foundProcs.add(proc.getCommonProcess()); 1621 } 1622 } 1623 } 1624 } 1625 ArrayList<ProcessState> outProcs = new ArrayList<ProcessState>(foundProcs.size()); 1626 for (int i=0; i<foundProcs.size(); i++) { 1627 ProcessState proc = foundProcs.valueAt(i); 1628 if (proc.computeProcessTimeLocked(screenStates, memStates, procStates, now) > 0) { 1629 outProcs.add(proc); 1630 if (procStates != sortProcStates) { 1631 proc.computeProcessTimeLocked(screenStates, memStates, sortProcStates, now); 1632 } 1633 } 1634 } 1635 Collections.sort(outProcs, ProcessState.COMPARATOR); 1636 return outProcs; 1637 } 1638 1639 public void dumpCheckinLocked(PrintWriter pw, String reqPackage) { 1640 final long now = SystemClock.uptimeMillis(); 1641 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 1642 mPackages.getMap(); 1643 pw.println("vers,5"); 1644 pw.print("period,"); pw.print(mTimePeriodStartClockStr); 1645 pw.print(","); pw.print(mTimePeriodStartRealtime); pw.print(","); 1646 pw.print(mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime); 1647 boolean partial = true; 1648 if ((mFlags&FLAG_SHUTDOWN) != 0) { 1649 pw.print(",shutdown"); 1650 partial = false; 1651 } 1652 if ((mFlags&FLAG_SYSPROPS) != 0) { 1653 pw.print(",sysprops"); 1654 partial = false; 1655 } 1656 if ((mFlags&FLAG_COMPLETE) != 0) { 1657 pw.print(",complete"); 1658 partial = false; 1659 } 1660 if (partial) { 1661 pw.print(",partial"); 1662 } 1663 if (mHasSwappedOutPss) { 1664 pw.print(",swapped-out-pss"); 1665 } 1666 pw.println(); 1667 pw.print("config,"); pw.println(mRuntime); 1668 for (int ip=0; ip<pkgMap.size(); ip++) { 1669 final String pkgName = pkgMap.keyAt(ip); 1670 if (reqPackage != null && !reqPackage.equals(pkgName)) { 1671 continue; 1672 } 1673 final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip); 1674 for (int iu=0; iu<uids.size(); iu++) { 1675 final int uid = uids.keyAt(iu); 1676 final LongSparseArray<PackageState> vpkgs = uids.valueAt(iu); 1677 for (int iv=0; iv<vpkgs.size(); iv++) { 1678 final long vers = vpkgs.keyAt(iv); 1679 final PackageState pkgState = vpkgs.valueAt(iv); 1680 final int NPROCS = pkgState.mProcesses.size(); 1681 final int NSRVS = pkgState.mServices.size(); 1682 for (int iproc=0; iproc<NPROCS; iproc++) { 1683 ProcessState proc = pkgState.mProcesses.valueAt(iproc); 1684 proc.dumpPackageProcCheckin(pw, pkgName, uid, vers, 1685 pkgState.mProcesses.keyAt(iproc), now); 1686 } 1687 for (int isvc=0; isvc<NSRVS; isvc++) { 1688 final String serviceName = DumpUtils.collapseString(pkgName, 1689 pkgState.mServices.keyAt(isvc)); 1690 final ServiceState svc = pkgState.mServices.valueAt(isvc); 1691 svc.dumpTimesCheckin(pw, pkgName, uid, vers, serviceName, now); 1692 } 1693 } 1694 } 1695 } 1696 1697 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 1698 for (int ip=0; ip<procMap.size(); ip++) { 1699 String procName = procMap.keyAt(ip); 1700 SparseArray<ProcessState> uids = procMap.valueAt(ip); 1701 for (int iu=0; iu<uids.size(); iu++) { 1702 final int uid = uids.keyAt(iu); 1703 final ProcessState procState = uids.valueAt(iu); 1704 procState.dumpProcCheckin(pw, procName, uid, now); 1705 } 1706 } 1707 pw.print("total"); 1708 DumpUtils.dumpAdjTimesCheckin(pw, ",", mMemFactorDurations, mMemFactor, mStartTime, now); 1709 pw.println(); 1710 final int sysMemUsageCount = mSysMemUsage.getKeyCount(); 1711 if (sysMemUsageCount > 0) { 1712 pw.print("sysmemusage"); 1713 for (int i=0; i<sysMemUsageCount; i++) { 1714 final int key = mSysMemUsage.getKeyAt(i); 1715 final int type = SparseMappingTable.getIdFromKey(key); 1716 pw.print(","); 1717 DumpUtils.printProcStateTag(pw, type); 1718 for (int j=SYS_MEM_USAGE_SAMPLE_COUNT; j<SYS_MEM_USAGE_COUNT; j++) { 1719 if (j > SYS_MEM_USAGE_CACHED_MINIMUM) { 1720 pw.print(":"); 1721 } 1722 pw.print(mSysMemUsage.getValue(key, j)); 1723 } 1724 } 1725 } 1726 pw.println(); 1727 TotalMemoryUseCollection totalMem = new TotalMemoryUseCollection(ALL_SCREEN_ADJ, 1728 ALL_MEM_ADJ); 1729 computeTotalMemoryUse(totalMem, now); 1730 pw.print("weights,"); 1731 pw.print(totalMem.totalTime); 1732 pw.print(","); 1733 pw.print(totalMem.sysMemCachedWeight); 1734 pw.print(":"); 1735 pw.print(totalMem.sysMemSamples); 1736 pw.print(","); 1737 pw.print(totalMem.sysMemFreeWeight); 1738 pw.print(":"); 1739 pw.print(totalMem.sysMemSamples); 1740 pw.print(","); 1741 pw.print(totalMem.sysMemZRamWeight); 1742 pw.print(":"); 1743 pw.print(totalMem.sysMemSamples); 1744 pw.print(","); 1745 pw.print(totalMem.sysMemKernelWeight); 1746 pw.print(":"); 1747 pw.print(totalMem.sysMemSamples); 1748 pw.print(","); 1749 pw.print(totalMem.sysMemNativeWeight); 1750 pw.print(":"); 1751 pw.print(totalMem.sysMemSamples); 1752 for (int i=0; i<STATE_COUNT; i++) { 1753 pw.print(","); 1754 pw.print(totalMem.processStateWeight[i]); 1755 pw.print(":"); 1756 pw.print(totalMem.processStateSamples[i]); 1757 } 1758 pw.println(); 1759 1760 final int NPAGETYPES = mPageTypeLabels.size(); 1761 for (int i=0; i<NPAGETYPES; i++) { 1762 pw.print("availablepages,"); 1763 pw.print(mPageTypeLabels.get(i)); 1764 pw.print(","); 1765 pw.print(mPageTypeZones.get(i)); 1766 pw.print(","); 1767 final int[] sizes = mPageTypeSizes.get(i); 1768 final int N = sizes == null ? 0 : sizes.length; 1769 for (int j=0; j<N; j++) { 1770 if (j != 0) { 1771 pw.print(","); 1772 } 1773 pw.print(sizes[j]); 1774 } 1775 pw.println(); 1776 } 1777 } 1778 1779 public void writeToProto(ProtoOutputStream proto, long fieldId, long now) { 1780 final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap = 1781 mPackages.getMap(); 1782 1783 final long token = proto.start(fieldId); 1784 proto.write(ProcessStatsSectionProto.START_REALTIME_MS, mTimePeriodStartRealtime); 1785 proto.write(ProcessStatsSectionProto.END_REALTIME_MS, 1786 mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime); 1787 proto.write(ProcessStatsSectionProto.START_UPTIME_MS, mTimePeriodStartUptime); 1788 proto.write(ProcessStatsSectionProto.END_UPTIME_MS, mTimePeriodEndUptime); 1789 proto.write(ProcessStatsSectionProto.RUNTIME, mRuntime); 1790 proto.write(ProcessStatsSectionProto.HAS_SWAPPED_PSS, mHasSwappedOutPss); 1791 boolean partial = true; 1792 if ((mFlags&FLAG_SHUTDOWN) != 0) { 1793 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SHUTDOWN); 1794 partial = false; 1795 } 1796 if ((mFlags&FLAG_SYSPROPS) != 0) { 1797 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SYSPROPS); 1798 partial = false; 1799 } 1800 if ((mFlags&FLAG_COMPLETE) != 0) { 1801 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_COMPLETE); 1802 partial = false; 1803 } 1804 if (partial) { 1805 proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_PARTIAL); 1806 } 1807 1808 ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap(); 1809 for (int ip=0; ip<procMap.size(); ip++) { 1810 String procName = procMap.keyAt(ip); 1811 SparseArray<ProcessState> uids = procMap.valueAt(ip); 1812 for (int iu=0; iu<uids.size(); iu++) { 1813 final int uid = uids.keyAt(iu); 1814 final ProcessState procState = uids.valueAt(iu); 1815 procState.writeToProto(proto, ProcessStatsSectionProto.PROCESS_STATS, procName, uid, now); 1816 } 1817 } 1818 proto.end(token); 1819 } 1820 1821 final public static class ProcessStateHolder { 1822 public final long appVersion; 1823 public ProcessState state; 1824 1825 public ProcessStateHolder(long _appVersion) { 1826 appVersion = _appVersion; 1827 } 1828 } 1829 1830 public static final class PackageState { 1831 public final ArrayMap<String, ProcessState> mProcesses 1832 = new ArrayMap<String, ProcessState>(); 1833 public final ArrayMap<String, ServiceState> mServices 1834 = new ArrayMap<String, ServiceState>(); 1835 public final String mPackageName; 1836 public final int mUid; 1837 1838 public PackageState(String packageName, int uid) { 1839 mUid = uid; 1840 mPackageName = packageName; 1841 } 1842 } 1843 1844 public static final class ProcessDataCollection { 1845 final int[] screenStates; 1846 final int[] memStates; 1847 final int[] procStates; 1848 1849 public long totalTime; 1850 public long numPss; 1851 public long minPss; 1852 public long avgPss; 1853 public long maxPss; 1854 public long minUss; 1855 public long avgUss; 1856 public long maxUss; 1857 1858 public ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates) { 1859 screenStates = _screenStates; 1860 memStates = _memStates; 1861 procStates = _procStates; 1862 } 1863 1864 void print(PrintWriter pw, long overallTime, boolean full) { 1865 if (totalTime > overallTime) { 1866 pw.print("*"); 1867 } 1868 DumpUtils.printPercent(pw, (double) totalTime / (double) overallTime); 1869 if (numPss > 0) { 1870 pw.print(" ("); 1871 DebugUtils.printSizeValue(pw, minPss * 1024); 1872 pw.print("-"); 1873 DebugUtils.printSizeValue(pw, avgPss * 1024); 1874 pw.print("-"); 1875 DebugUtils.printSizeValue(pw, maxPss * 1024); 1876 pw.print("/"); 1877 DebugUtils.printSizeValue(pw, minUss * 1024); 1878 pw.print("-"); 1879 DebugUtils.printSizeValue(pw, avgUss * 1024); 1880 pw.print("-"); 1881 DebugUtils.printSizeValue(pw, maxUss * 1024); 1882 if (full) { 1883 pw.print(" over "); 1884 pw.print(numPss); 1885 } 1886 pw.print(")"); 1887 } 1888 } 1889 } 1890 1891 public static class TotalMemoryUseCollection { 1892 final int[] screenStates; 1893 final int[] memStates; 1894 1895 public TotalMemoryUseCollection(int[] _screenStates, int[] _memStates) { 1896 screenStates = _screenStates; 1897 memStates = _memStates; 1898 } 1899 1900 public long totalTime; 1901 public long[] processStatePss = new long[STATE_COUNT]; 1902 public double[] processStateWeight = new double[STATE_COUNT]; 1903 public long[] processStateTime = new long[STATE_COUNT]; 1904 public int[] processStateSamples = new int[STATE_COUNT]; 1905 public long[] sysMemUsage = new long[SYS_MEM_USAGE_COUNT]; 1906 public double sysMemCachedWeight; 1907 public double sysMemFreeWeight; 1908 public double sysMemZRamWeight; 1909 public double sysMemKernelWeight; 1910 public double sysMemNativeWeight; 1911 public int sysMemSamples; 1912 public boolean hasSwappedOutPss; 1913 } 1914 1915} 1916