1 /* 2 * Copyright (C) 2020 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 17 package com.android.server.am; 18 19 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; 20 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; 21 import static android.os.Process.FIRST_APPLICATION_UID; 22 import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS; 23 import static android.view.Display.INVALID_DISPLAY; 24 25 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 26 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW; 27 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE; 28 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL; 29 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; 30 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS; 31 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RSS; 32 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS; 33 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RSS; 34 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 35 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 36 import static com.android.server.am.ActivityManagerService.DUMP_MEM_OOM_ADJ; 37 import static com.android.server.am.ActivityManagerService.DUMP_MEM_OOM_LABEL; 38 import static com.android.server.am.ActivityManagerService.GC_BACKGROUND_PROCESSES_MSG; 39 import static com.android.server.am.ActivityManagerService.KSM_SHARED; 40 import static com.android.server.am.ActivityManagerService.KSM_SHARING; 41 import static com.android.server.am.ActivityManagerService.KSM_UNSHARED; 42 import static com.android.server.am.ActivityManagerService.KSM_VOLATILE; 43 import static com.android.server.am.ActivityManagerService.REPORT_MEM_USAGE_MSG; 44 import static com.android.server.am.ActivityManagerService.appendBasicMemEntry; 45 import static com.android.server.am.ActivityManagerService.appendMemBucket; 46 import static com.android.server.am.ActivityManagerService.appendMemInfo; 47 import static com.android.server.am.ActivityManagerService.getKsmInfo; 48 import static com.android.server.am.ActivityManagerService.stringifyKBSize; 49 import static com.android.server.am.LowMemDetector.ADJ_MEM_FACTOR_NOTHING; 50 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; 51 import static com.android.server.wm.ActivityTaskManagerService.DUMP_ACTIVITIES_CMD; 52 53 import android.annotation.BroadcastBehavior; 54 import android.annotation.NonNull; 55 import android.annotation.Nullable; 56 import android.app.ActivityManager; 57 import android.app.ActivityThread; 58 import android.app.IApplicationThread; 59 import android.app.ProfilerInfo; 60 import android.content.ComponentCallbacks2; 61 import android.content.ContentResolver; 62 import android.content.Context; 63 import android.content.Intent; 64 import android.content.pm.PackageManager.NameNotFoundException; 65 import android.net.Uri; 66 import android.os.Binder; 67 import android.os.Build; 68 import android.os.Debug; 69 import android.os.Flags; 70 import android.os.Handler; 71 import android.os.Looper; 72 import android.os.Message; 73 import android.os.ParcelFileDescriptor; 74 import android.os.RemoteException; 75 import android.os.ServiceManager; 76 import android.os.SystemClock; 77 import android.os.SystemProperties; 78 import android.os.UserHandle; 79 import android.provider.DeviceConfig; 80 import android.provider.DeviceConfig.Properties; 81 import android.text.TextUtils; 82 import android.util.ArrayMap; 83 import android.util.DebugUtils; 84 import android.util.FeatureFlagUtils; 85 import android.util.Pair; 86 import android.util.Slog; 87 import android.util.SparseArray; 88 import android.util.SparseIntArray; 89 import android.util.StatsEvent; 90 import android.util.proto.ProtoOutputStream; 91 92 import com.android.internal.annotations.GuardedBy; 93 import com.android.internal.app.ProcessMap; 94 import com.android.internal.app.procstats.ProcessStats; 95 import com.android.internal.os.BackgroundThread; 96 import com.android.internal.os.BinderInternal; 97 import com.android.internal.os.ProcessCpuTracker; 98 import com.android.internal.util.DumpUtils; 99 import com.android.internal.util.FastPrintWriter; 100 import com.android.internal.util.FrameworkStatsLog; 101 import com.android.internal.util.MemInfoReader; 102 import com.android.internal.util.QuickSelect; 103 import com.android.server.am.LowMemDetector.MemFactor; 104 import com.android.server.power.stats.BatteryStatsImpl; 105 import com.android.server.utils.PriorityDump; 106 107 import java.io.FileDescriptor; 108 import java.io.IOException; 109 import java.io.PrintWriter; 110 import java.io.StringWriter; 111 import java.util.ArrayList; 112 import java.util.Collections; 113 import java.util.Comparator; 114 import java.util.HashMap; 115 import java.util.List; 116 import java.util.Map; 117 import java.util.concurrent.CountDownLatch; 118 import java.util.concurrent.atomic.AtomicBoolean; 119 import java.util.concurrent.atomic.AtomicInteger; 120 import java.util.concurrent.atomic.AtomicLong; 121 import java.util.function.Consumer; 122 import java.util.function.Predicate; 123 124 /** 125 * A helper class taking care of the profiling, memory and cpu sampling of apps 126 */ 127 public class AppProfiler { 128 private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM; 129 130 static final String TAG_PSS = TAG + POSTFIX_PSS; 131 static final String TAG_RSS = TAG + POSTFIX_RSS; 132 133 static final String TAG_OOM_ADJ = ActivityManagerService.TAG_OOM_ADJ; 134 135 /** Control over CPU and battery monitoring */ 136 // write battery stats every 30 minutes. 137 static final long BATTERY_STATS_TIME = 30 * 60 * 1000; 138 139 static final boolean MONITOR_CPU_USAGE = true; 140 141 // don't sample cpu less than every 5 seconds. 142 static final long MONITOR_CPU_MIN_TIME = 5 * 1000; 143 144 // wait possibly forever for next cpu sample. 145 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; 146 147 static final boolean MONITOR_THREAD_CPU_USAGE = false; 148 149 static final String ACTIVITY_START_PSS_DEFER_CONFIG = "activity_start_pss_defer"; 150 151 /** 152 * Broadcast sent when heap dump collection has been completed. 153 */ 154 @BroadcastBehavior(includeBackground = true, protectedBroadcast = true) 155 private static final String ACTION_HEAP_DUMP_FINISHED = 156 "com.android.internal.intent.action.HEAP_DUMP_FINISHED"; 157 158 /** 159 * The process we are reporting 160 */ 161 private static final String EXTRA_HEAP_DUMP_PROCESS_NAME = 162 "com.android.internal.extra.heap_dump.PROCESS_NAME"; 163 164 /** 165 * The size limit the process reached. 166 */ 167 private static final String EXTRA_HEAP_DUMP_SIZE_BYTES = 168 "com.android.internal.extra.heap_dump.SIZE_BYTES"; 169 170 /** 171 * Whether the user initiated the dump or not. 172 */ 173 private static final String EXTRA_HEAP_DUMP_IS_USER_INITIATED = 174 "com.android.internal.extra.heap_dump.IS_USER_INITIATED"; 175 176 /** 177 * Optional name of package to directly launch. 178 */ 179 private static final String EXTRA_HEAP_DUMP_REPORT_PACKAGE = 180 "com.android.internal.extra.heap_dump.REPORT_PACKAGE"; 181 182 /** 183 * How long we defer PSS gathering while activities are starting, in milliseconds. 184 * This is adjustable via DeviceConfig. If it is zero or negative, no PSS deferral 185 * is done. 186 */ 187 private volatile long mPssDeferralTime = 0; 188 189 /** 190 * Processes we want to collect PSS or RSS data from. 191 */ 192 @GuardedBy("mProfilerLock") 193 private final ArrayList<ProcessProfileRecord> mPendingPssOrRssProfiles = new ArrayList<>(); 194 195 /** 196 * Depth of overlapping activity-start PSS deferral notes 197 */ 198 private final AtomicInteger mActivityStartingNesting = new AtomicInteger(0); 199 200 /** 201 * Last time we requested PSS data of all processes. 202 */ 203 @GuardedBy("mProfilerLock") 204 private long mLastFullPssTime = SystemClock.uptimeMillis(); 205 206 /** 207 * If set, the next time we collect PSS or RSS data we should do a full collection with data 208 * from native processes and the kernel. 209 */ 210 @GuardedBy("mProfilerLock") 211 private boolean mFullPssOrRssPending = false; 212 213 /** 214 * If true, we are running under a test environment so will sample PSS or RSS from processes 215 * much more rapidly to try to collect better data when the tests are rapidly running through 216 * apps. 217 */ 218 private volatile boolean mTestPssOrRssMode = false; 219 220 private final LowMemDetector mLowMemDetector; 221 222 /** 223 * Allow the current computed overall memory level of the system to go down? 224 * This is set to false when we are killing processes for reasons other than 225 * memory management, so that the now smaller process list will not be taken as 226 * an indication that memory is tighter. 227 */ 228 @GuardedBy("mService") 229 private boolean mAllowLowerMemLevel = false; 230 231 /** 232 * The last computed memory level, for holding when we are in a state that 233 * processes are going away for other reasons. 234 */ 235 @GuardedBy("mService") 236 private @MemFactor int mLastMemoryLevel = ADJ_MEM_FACTOR_NORMAL; 237 238 @GuardedBy("mService") 239 private @MemFactor int mMemFactorOverride = ADJ_MEM_FACTOR_NOTHING; 240 241 /** 242 * The last total number of process we have, to determine if changes actually look 243 * like a shrinking number of process due to lower RAM. 244 */ 245 @GuardedBy("mService") 246 private int mLastNumProcesses; 247 248 /** 249 * Total time spent with RAM that has been added in the past since the last idle time. 250 */ 251 @GuardedBy("mProcLock") 252 private long mLowRamTimeSinceLastIdle = 0; 253 254 /** 255 * If RAM is currently low, when that horrible situation started. 256 */ 257 @GuardedBy("mProcLock") 258 private long mLowRamStartTime = 0; 259 260 /** 261 * Last time we report a memory usage. 262 */ 263 @GuardedBy("mService") 264 private long mLastMemUsageReportTime = 0; 265 266 /** 267 * List of processes that should gc as soon as things are idle. 268 */ 269 @GuardedBy("mProfilerLock") 270 private final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<>(); 271 272 /** 273 * Stores a map of process name -> agent string. When a process is started and mAgentAppMap 274 * is not null, this map is checked and the mapped agent installed during bind-time. Note: 275 * A non-null agent in mProfileInfo overrides this. 276 */ 277 @GuardedBy("mProfilerLock") 278 private @Nullable Map<String, String> mAppAgentMap = null; 279 280 @GuardedBy("mProfilerLock") 281 private int mProfileType = 0; 282 283 @GuardedBy("mProfilerLock") 284 private final ProfileData mProfileData = new ProfileData(); 285 286 @GuardedBy("mProfilerLock") 287 private final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>(); 288 289 @GuardedBy("mProfilerLock") 290 private String mMemWatchDumpProcName; 291 292 @GuardedBy("mProfilerLock") 293 private Uri mMemWatchDumpUri; 294 295 @GuardedBy("mProfilerLock") 296 private int mMemWatchDumpPid; 297 298 @GuardedBy("mProfilerLock") 299 private int mMemWatchDumpUid; 300 301 @GuardedBy("mProfilerLock") 302 private boolean mMemWatchIsUserInitiated; 303 304 @GuardedBy("mService") 305 boolean mHasHomeProcess; 306 307 @GuardedBy("mService") 308 boolean mHasPreviousProcess; 309 310 /** 311 * Used to collect per-process CPU use for ANRs, battery stats, etc. 312 * Must acquire this object's lock when accessing it. 313 * NOTE: this lock will be held while doing long operations (trawling 314 * through all processes in /proc), so it should never be acquired by 315 * any critical paths such as when holding the main activity manager lock. 316 */ 317 private final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 318 MONITOR_THREAD_CPU_USAGE); 319 private final AtomicLong mLastCpuTime = new AtomicLong(0); 320 private final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 321 private final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1); 322 323 private volatile long mLastWriteTime = 0; 324 325 /** 326 * Runtime CPU use collection thread. This object's lock is used to 327 * perform synchronization with the thread (notifying it to run). 328 */ 329 private final Thread mProcessCpuThread; 330 331 private final ActivityManagerService mService; 332 private final Handler mBgHandler; 333 334 final CachedAppsWatermarkData mCachedAppsWatermarkData = new CachedAppsWatermarkData(); 335 336 /** 337 * The lock to guard some of the profiling data here and {@link ProcessProfileRecord}. 338 * 339 * <p> 340 * The function suffix with this lock would be "-LPf" (Locked with Profiler lock). 341 * </p> 342 */ 343 final Object mProfilerLock = new Object(); 344 345 final ActivityManagerGlobalLock mProcLock; 346 347 /** 348 * Observe DeviceConfig changes to the PSS calculation interval 349 */ 350 private final DeviceConfig.OnPropertiesChangedListener mPssDelayConfigListener = 351 new DeviceConfig.OnPropertiesChangedListener() { 352 @Override 353 public void onPropertiesChanged(Properties properties) { 354 if (properties.getKeyset().contains(ACTIVITY_START_PSS_DEFER_CONFIG)) { 355 mPssDeferralTime = properties.getLong(ACTIVITY_START_PSS_DEFER_CONFIG, 0); 356 if (DEBUG_PSS) { 357 Slog.d(TAG_PSS, "Activity-start PSS delay now " 358 + mPssDeferralTime + " ms"); 359 } 360 } 361 } 362 }; 363 364 private class ProfileData { 365 private String mProfileApp = null; 366 private ProcessRecord mProfileProc = null; 367 private ProfilerInfo mProfilerInfo = null; 368 setProfileApp(String profileApp)369 void setProfileApp(String profileApp) { 370 mProfileApp = profileApp; 371 if (mService.mAtmInternal != null) { 372 mService.mAtmInternal.setProfileApp(profileApp); 373 } 374 } 375 getProfileApp()376 String getProfileApp() { 377 return mProfileApp; 378 } 379 setProfileProc(ProcessRecord profileProc)380 void setProfileProc(ProcessRecord profileProc) { 381 mProfileProc = profileProc; 382 if (mService.mAtmInternal != null) { 383 mService.mAtmInternal.setProfileProc(profileProc == null ? null 384 : profileProc.getWindowProcessController()); 385 } 386 } 387 getProfileProc()388 ProcessRecord getProfileProc() { 389 return mProfileProc; 390 } 391 setProfilerInfo(ProfilerInfo profilerInfo)392 void setProfilerInfo(ProfilerInfo profilerInfo) { 393 mProfilerInfo = profilerInfo; 394 if (mService.mAtmInternal != null) { 395 mService.mAtmInternal.setProfilerInfo(profilerInfo); 396 } 397 } 398 getProfilerInfo()399 ProfilerInfo getProfilerInfo() { 400 return mProfilerInfo; 401 } 402 } 403 404 /** 405 * A simple data class holding the information about the cached apps high watermark. 406 * 407 * Keep it sync with the frameworks/proto_logging/stats/atoms.proto 408 */ 409 class CachedAppsWatermarkData { 410 /** The high water mark of the number of cached apps. */ 411 @GuardedBy("mProcLock") 412 int mCachedAppHighWatermark; 413 414 /** 415 * The uptime (in seconds) at the high watermark. 416 * Note this is going to be pull metrics, so we'll need the timestamp here. 417 */ 418 @GuardedBy("mProcLock") 419 int mUptimeInSeconds; 420 421 /** The number of binder proxy at that high water mark. */ 422 @GuardedBy("mProcLock") 423 int mBinderProxySnapshot; 424 425 /** Free physical memory (in kb) on device. */ 426 @GuardedBy("mProcLock") 427 int mFreeInKb; 428 429 /** Cched physical memory (in kb) on device. */ 430 @GuardedBy("mProcLock") 431 int mCachedInKb; 432 433 /** zram (in kb) on device. */ 434 @GuardedBy("mProcLock") 435 int mZramInKb; 436 437 /** Kernel memory (in kb) on device. */ 438 @GuardedBy("mProcLock") 439 int mKernelInKb; 440 441 /** The number of apps in frozen state. */ 442 @GuardedBy("mProcLock") 443 int mNumOfFrozenApps; 444 445 /** The longest frozen time (now - last_frozen) in current frozen apps. */ 446 @GuardedBy("mProcLock") 447 int mLongestFrozenTimeInSeconds; 448 449 /** The shortest frozen time (now - last_frozen) in current frozen apps. */ 450 @GuardedBy("mProcLock") 451 int mShortestFrozenTimeInSeconds; 452 453 /** The mean frozen time (now - last_frozen) in current frozen apps. */ 454 @GuardedBy("mProcLock") 455 int mMeanFrozenTimeInSeconds; 456 457 /** The average frozen time (now - last_frozen) in current frozen apps. */ 458 @GuardedBy("mProcLock") 459 int mAverageFrozenTimeInSeconds; 460 461 /** 462 * This is an array holding the frozen app durations temporarily 463 * while updating the cached app high watermark. 464 */ 465 @GuardedBy("mProcLock") 466 private long[] mCachedAppFrozenDurations; 467 468 /** 469 * The earliest frozen timestamp within the frozen apps. 470 */ 471 @GuardedBy("mProcLock") 472 private long mEarliestFrozenTimestamp; 473 474 /** 475 * The most recent frozen timestamp within the frozen apps. 476 */ 477 @GuardedBy("mProcLock") 478 private long mLatestFrozenTimestamp; 479 480 /** 481 * The sum of total frozen durations of all frozen apps. 482 */ 483 @GuardedBy("mProcLock") 484 private long mTotalFrozenDurations; 485 486 @GuardedBy("mProcLock") updateCachedAppsHighWatermarkIfNecessaryLocked(int numOfCachedApps, long now)487 void updateCachedAppsHighWatermarkIfNecessaryLocked(int numOfCachedApps, long now) { 488 if (numOfCachedApps > mCachedAppHighWatermark) { 489 mCachedAppHighWatermark = numOfCachedApps; 490 mUptimeInSeconds = (int) (now / 1000); 491 492 // The rest of the updates are pretty costly, do it in a separated handler. 493 mService.mHandler.removeMessages( 494 ActivityManagerService.UPDATE_CACHED_APP_HIGH_WATERMARK); 495 mService.mHandler.obtainMessage( 496 ActivityManagerService.UPDATE_CACHED_APP_HIGH_WATERMARK, Long.valueOf(now)) 497 .sendToTarget(); 498 } 499 } 500 updateCachedAppsSnapshot(long now)501 void updateCachedAppsSnapshot(long now) { 502 synchronized (mProcLock) { 503 mEarliestFrozenTimestamp = now; 504 mLatestFrozenTimestamp = 0L; 505 mTotalFrozenDurations = 0L; 506 mNumOfFrozenApps = 0; 507 final int lruSize = mService.mProcessList.getLruSizeLOSP(); 508 if (mCachedAppFrozenDurations == null 509 || mCachedAppFrozenDurations.length < lruSize) { 510 mCachedAppFrozenDurations = new long[Math.max( 511 lruSize, mService.mConstants.CUR_MAX_CACHED_PROCESSES)]; 512 } 513 mService.mProcessList.forEachLruProcessesLOSP(true, app -> { 514 if (app.mOptRecord.isFrozen()) { 515 final long freezeTime = app.mOptRecord.getFreezeUnfreezeTime(); 516 if (freezeTime < mEarliestFrozenTimestamp) { 517 mEarliestFrozenTimestamp = freezeTime; 518 } 519 if (freezeTime > mLatestFrozenTimestamp) { 520 mLatestFrozenTimestamp = freezeTime; 521 } 522 final long duration = now - freezeTime; 523 mTotalFrozenDurations += duration; 524 mCachedAppFrozenDurations[mNumOfFrozenApps++] = duration; 525 } 526 }); 527 if (mNumOfFrozenApps > 0) { 528 mLongestFrozenTimeInSeconds = (int) ((now - mEarliestFrozenTimestamp) / 1000); 529 mShortestFrozenTimeInSeconds = (int) ((now - mLatestFrozenTimestamp) / 1000); 530 mAverageFrozenTimeInSeconds = 531 (int) ((mTotalFrozenDurations / mNumOfFrozenApps) / 1000); 532 mMeanFrozenTimeInSeconds = (int) (QuickSelect.select(mCachedAppFrozenDurations, 533 0, mNumOfFrozenApps, mNumOfFrozenApps / 2) / 1000); 534 } 535 536 mBinderProxySnapshot = 0; 537 final SparseIntArray counts = BinderInternal.nGetBinderProxyPerUidCounts(); 538 if (counts != null) { 539 for (int i = 0, size = counts.size(); i < size; i++) { 540 final int uid = counts.keyAt(i); 541 final UidRecord uidRec = mService.mProcessList.getUidRecordLOSP(uid); 542 if (uidRec != null) { 543 mBinderProxySnapshot += counts.valueAt(i); 544 } 545 } 546 } 547 548 final MemInfoReader memInfo = new MemInfoReader(); 549 memInfo.readMemInfo(); 550 mFreeInKb = (int) memInfo.getFreeSizeKb(); 551 mCachedInKb = (int) memInfo.getCachedSizeKb(); 552 mZramInKb = (int) memInfo.getZramTotalSizeKb(); 553 mKernelInKb = (int) memInfo.getKernelUsedSizeKb(); 554 } 555 } 556 557 @NonNull getCachedAppsHighWatermarkStats(int atomTag, boolean resetAfterPull)558 StatsEvent getCachedAppsHighWatermarkStats(int atomTag, boolean resetAfterPull) { 559 synchronized (mProcLock) { 560 final StatsEvent event = FrameworkStatsLog.buildStatsEvent(atomTag, 561 mCachedAppHighWatermark, 562 mUptimeInSeconds, 563 mBinderProxySnapshot, 564 mFreeInKb, 565 mCachedInKb, 566 mZramInKb, 567 mKernelInKb, 568 mNumOfFrozenApps, 569 mLongestFrozenTimeInSeconds, 570 mShortestFrozenTimeInSeconds, 571 mMeanFrozenTimeInSeconds, 572 mAverageFrozenTimeInSeconds); 573 if (resetAfterPull) { 574 mCachedAppHighWatermark = 0; 575 mUptimeInSeconds = 0; 576 mBinderProxySnapshot = 0; 577 mFreeInKb = 0; 578 mCachedInKb = 0; 579 mZramInKb = 0; 580 mKernelInKb = 0; 581 mNumOfFrozenApps = 0; 582 mLongestFrozenTimeInSeconds = 0; 583 mShortestFrozenTimeInSeconds = 0; 584 mMeanFrozenTimeInSeconds = 0; 585 mAverageFrozenTimeInSeconds = 0; 586 } 587 return event; 588 } 589 } 590 } 591 592 private class BgHandler extends Handler { 593 static final int COLLECT_PSS_BG_MSG = 1; 594 static final int DEFER_PSS_MSG = 2; 595 static final int STOP_DEFERRING_PSS_MSG = 3; 596 static final int MEMORY_PRESSURE_CHANGED = 4; BgHandler(Looper looper)597 BgHandler(Looper looper) { 598 super(looper); 599 } 600 601 @Override handleMessage(Message msg)602 public void handleMessage(Message msg) { 603 switch (msg.what) { 604 case COLLECT_PSS_BG_MSG: 605 if (isProfilingPss()) { 606 collectPssInBackground(); 607 } else { 608 collectRssInBackground(); 609 } 610 break; 611 case DEFER_PSS_MSG: 612 deferPssForActivityStart(); 613 break; 614 case STOP_DEFERRING_PSS_MSG: 615 stopDeferPss(); 616 break; 617 case MEMORY_PRESSURE_CHANGED: 618 synchronized (mService) { 619 handleMemoryPressureChangedLocked(msg.arg1, msg.arg2); 620 } 621 break; 622 } 623 } 624 } 625 collectPssInBackground()626 private void collectPssInBackground() { 627 long start = SystemClock.uptimeMillis(); 628 MemInfoReader memInfo = null; 629 synchronized (mProfilerLock) { 630 if (mFullPssOrRssPending) { 631 mFullPssOrRssPending = false; 632 memInfo = new MemInfoReader(); 633 } 634 } 635 if (memInfo != null) { 636 updateCpuStatsNow(); 637 long nativeTotalPss = 0; 638 final List<ProcessCpuTracker.Stats> stats; 639 synchronized (mProcessCpuTracker) { 640 stats = mProcessCpuTracker.getStats(st -> { 641 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID; 642 }); 643 } 644 645 if (!mService.mConstants.APP_PROFILER_PSS_PROFILING_DISABLED) { 646 final int numOfStats = stats.size(); 647 for (int j = 0; j < numOfStats; j++) { 648 synchronized (mService.mPidsSelfLocked) { 649 if (mService.mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) { 650 // This is one of our own processes; skip it. 651 continue; 652 } 653 } 654 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null); 655 } 656 } 657 658 memInfo.readMemInfo(); 659 synchronized (mService.mProcessStats.mLock) { 660 if (DEBUG_PSS) { 661 Slog.d(TAG_PSS, "Collected native and kernel memory in " 662 + (SystemClock.uptimeMillis() - start) + "ms"); 663 } 664 final long cachedKb = memInfo.getCachedSizeKb(); 665 final long freeKb = memInfo.getFreeSizeKb(); 666 final long zramKb = memInfo.getZramTotalSizeKb(); 667 final long kernelKb = memInfo.getKernelUsedSizeKb(); 668 EventLogTags.writeAmMeminfo(cachedKb * 1024, freeKb * 1024, zramKb * 1024, 669 kernelKb * 1024, nativeTotalPss * 1024); 670 mService.mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb, 671 nativeTotalPss); 672 } 673 } 674 675 int num = 0; 676 long[] tmp = new long[3]; 677 do { 678 ProcessProfileRecord profile; 679 int procState; 680 int statType; 681 int pid = -1; 682 long lastPssTime; 683 synchronized (mProfilerLock) { 684 if (mPendingPssOrRssProfiles.size() <= 0) { 685 if (mTestPssOrRssMode || DEBUG_PSS) { 686 Slog.d(TAG_PSS, 687 "Collected pss of " + num + " processes in " 688 + (SystemClock.uptimeMillis() - start) + "ms"); 689 } 690 mPendingPssOrRssProfiles.clear(); 691 return; 692 } 693 profile = mPendingPssOrRssProfiles.remove(0); 694 procState = profile.getPssProcState(); 695 statType = profile.getPssStatType(); 696 lastPssTime = profile.getLastPssTime(); 697 long now = SystemClock.uptimeMillis(); 698 if (profile.getThread() != null && procState == profile.getSetProcState() 699 && (lastPssTime + ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) < now) { 700 pid = profile.getPid(); 701 } else { 702 profile.abortNextPssTime(); 703 if (DEBUG_PSS) { 704 Slog.d(TAG_PSS, "Skipped pss collection of " + pid 705 + ": still need " 706 + (lastPssTime + ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE - now) 707 + "ms until safe"); 708 } 709 profile = null; 710 pid = 0; 711 } 712 } 713 if (profile != null) { 714 long startTime = SystemClock.uptimeMillis(); 715 // skip background PSS calculation under the following situations: 716 // - app is capturing camera imagery 717 // - app is frozen and we have already collected PSS once. 718 final boolean skipPSSCollection = 719 (profile.mApp.mOptRecord != null 720 && profile.mApp.mOptRecord.skipPSSCollectionBecauseFrozen()) 721 || mService.isCameraActiveForUid(profile.mApp.uid) 722 || mService.mConstants.APP_PROFILER_PSS_PROFILING_DISABLED; 723 long pss = skipPSSCollection ? 0 : Debug.getPss(pid, tmp, null); 724 long endTime = SystemClock.uptimeMillis(); 725 synchronized (mProfilerLock) { 726 if (pss != 0 && profile.getThread() != null 727 && profile.getSetProcState() == procState 728 && profile.getPid() == pid && profile.getLastPssTime() == lastPssTime) { 729 num++; 730 profile.commitNextPssTime(); 731 recordPssSampleLPf(profile, procState, pss, tmp[0], tmp[1], tmp[2], 732 statType, endTime - startTime, SystemClock.uptimeMillis()); 733 } else { 734 profile.abortNextPssTime(); 735 if (DEBUG_PSS) { 736 Slog.d(TAG_PSS, "Skipped pss collection of " + pid 737 + ": " + (profile.getThread() == null ? "NO_THREAD " : "") 738 + (skipPSSCollection ? "SKIP_PSS_COLLECTION " : "") 739 + (profile.getPid() != pid ? "PID_CHANGED " : "") 740 + " initState=" + procState + " curState=" 741 + profile.getSetProcState() + " " 742 + (profile.getLastPssTime() != lastPssTime 743 ? "TIME_CHANGED" : "")); 744 } 745 } 746 } 747 } 748 } while (true); 749 } 750 isProfilingPss()751 boolean isProfilingPss() { 752 return !Flags.removeAppProfilerPssCollection() 753 || mService.mConstants.mForceEnablePssProfiling; 754 } 755 756 // This method is analogous to collectPssInBackground() and is intended to be used as a 757 // replacement if Flags.removeAppProfilerPssCollection() is enabled. References to PSS in 758 // methods outside of AppProfiler have generally been kept where a new RSS equivalent is not 759 // technically necessary. These can be updated once the flag is completely rolled out. collectRssInBackground()760 private void collectRssInBackground() { 761 long start = SystemClock.uptimeMillis(); 762 MemInfoReader memInfo = null; 763 synchronized (mProfilerLock) { 764 if (mFullPssOrRssPending) { 765 mFullPssOrRssPending = false; 766 memInfo = new MemInfoReader(); 767 } 768 } 769 if (memInfo != null) { 770 updateCpuStatsNow(); 771 long nativeTotalRss = 0; 772 final List<ProcessCpuTracker.Stats> stats; 773 synchronized (mProcessCpuTracker) { 774 stats = mProcessCpuTracker.getStats(st -> { 775 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID; 776 }); 777 } 778 779 // We assume that if PSS collection isn't needed or desired, RSS collection can be 780 // disabled as well. 781 if (!mService.mConstants.APP_PROFILER_PSS_PROFILING_DISABLED) { 782 final int numOfStats = stats.size(); 783 for (int j = 0; j < numOfStats; j++) { 784 synchronized (mService.mPidsSelfLocked) { 785 if (mService.mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) { 786 // This is one of our own processes; skip it. 787 continue; 788 } 789 } 790 nativeTotalRss += Debug.getRss(stats.get(j).pid, null); 791 } 792 } 793 794 memInfo.readMemInfo(); 795 synchronized (mService.mProcessStats.mLock) { 796 // We assume that an enabled DEBUG_PSS can apply to RSS as well, since only one of 797 // either collectPssInBackground() or collectRssInBackground() will be used. 798 if (DEBUG_RSS) { 799 Slog.d(TAG_RSS, "Collected native and kernel memory in " 800 + (SystemClock.uptimeMillis() - start) + "ms"); 801 } 802 final long cachedKb = memInfo.getCachedSizeKb(); 803 final long freeKb = memInfo.getFreeSizeKb(); 804 final long zramKb = memInfo.getZramTotalSizeKb(); 805 final long kernelKb = memInfo.getKernelUsedSizeKb(); 806 // The last value needs to be updated in log tags to refer to RSS; this will be 807 // updated once the flag is fully rolled out. 808 EventLogTags.writeAmMeminfo(cachedKb * 1024, freeKb * 1024, zramKb * 1024, 809 kernelKb * 1024, nativeTotalRss * 1024); 810 mService.mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb, 811 nativeTotalRss); 812 } 813 } 814 815 // This loop differs from its original form in collectPssInBackground(), as it does not 816 // collect USS or SwapPss (since those are reported in smaps, not status). 817 int num = 0; 818 do { 819 ProcessProfileRecord profile; 820 int procState; 821 int statType; 822 int pid = -1; 823 long lastRssTime; 824 synchronized (mProfilerLock) { 825 if (mPendingPssOrRssProfiles.size() <= 0) { 826 if (mTestPssOrRssMode || DEBUG_RSS) { 827 Slog.d(TAG_RSS, 828 "Collected rss of " + num + " processes in " 829 + (SystemClock.uptimeMillis() - start) + "ms"); 830 } 831 mPendingPssOrRssProfiles.clear(); 832 return; 833 } 834 profile = mPendingPssOrRssProfiles.remove(0); 835 procState = profile.getPssProcState(); 836 statType = profile.getPssStatType(); 837 lastRssTime = profile.getLastPssTime(); 838 long now = SystemClock.uptimeMillis(); 839 if (profile.getThread() != null && procState == profile.getSetProcState() 840 && (lastRssTime + ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) < now) { 841 pid = profile.getPid(); 842 } else { 843 profile.abortNextPssTime(); 844 if (DEBUG_RSS) { 845 Slog.d(TAG_RSS, "Skipped rss collection of " + pid 846 + ": still need " 847 + (lastRssTime + ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE - now) 848 + "ms until safe"); 849 } 850 profile = null; 851 pid = 0; 852 } 853 } 854 if (profile != null) { 855 long startTime = SystemClock.uptimeMillis(); 856 // skip background RSS calculation under the following situations: 857 // - app is capturing camera imagery 858 // - app is frozen and we have already collected RSS once. 859 final boolean skipRSSCollection = 860 (profile.mApp.mOptRecord != null 861 && profile.mApp.mOptRecord.skipPSSCollectionBecauseFrozen()) 862 || mService.isCameraActiveForUid(profile.mApp.uid) 863 || mService.mConstants.APP_PROFILER_PSS_PROFILING_DISABLED; 864 long rss = skipRSSCollection ? 0 : Debug.getRss(pid, null); 865 long endTime = SystemClock.uptimeMillis(); 866 synchronized (mProfilerLock) { 867 if (rss != 0 && profile.getThread() != null 868 && profile.getSetProcState() == procState 869 && profile.getPid() == pid && profile.getLastPssTime() == lastRssTime) { 870 num++; 871 profile.commitNextPssTime(); 872 recordRssSampleLPf(profile, procState, rss, statType, endTime - startTime, 873 SystemClock.uptimeMillis()); 874 } else { 875 profile.abortNextPssTime(); 876 if (DEBUG_RSS) { 877 Slog.d(TAG_RSS, "Skipped rss collection of " + pid 878 + ": " + (profile.getThread() == null ? "NO_THREAD " : "") 879 + (skipRSSCollection ? "SKIP_RSS_COLLECTION " : "") 880 + (profile.getPid() != pid ? "PID_CHANGED " : "") 881 + " initState=" + procState + " curState=" 882 + profile.getSetProcState() + " " 883 + (profile.getLastPssTime() != lastRssTime 884 ? "TIME_CHANGED" : "")); 885 } 886 } 887 } 888 } 889 } while (true); 890 } 891 892 @GuardedBy("mProfilerLock") updateNextPssTimeLPf(int procState, ProcessProfileRecord profile, long now, boolean forceUpdate)893 void updateNextPssTimeLPf(int procState, ProcessProfileRecord profile, long now, 894 boolean forceUpdate) { 895 if (!forceUpdate) { 896 if (now <= profile.getNextPssTime() && now <= Math.max(profile.getLastPssTime() 897 + ProcessList.PSS_MAX_INTERVAL, profile.getLastStateTime() 898 + ProcessList.minTimeFromStateChange(mTestPssOrRssMode))) { 899 // update is not due, ignore it. 900 return; 901 } 902 if (!requestPssLPf(profile, procState)) { 903 return; 904 } 905 } 906 profile.setNextPssTime(profile.computeNextPssTime(procState, 907 mTestPssOrRssMode, mService.mAtmInternal.isSleeping(), now)); 908 } 909 910 /** 911 * Record new PSS sample for a process. 912 */ 913 @GuardedBy("mProfilerLock") recordPssSampleLPf(ProcessProfileRecord profile, int procState, long pss, long uss, long swapPss, long rss, int statType, long pssDuration, long now)914 private void recordPssSampleLPf(ProcessProfileRecord profile, int procState, long pss, long uss, 915 long swapPss, long rss, int statType, long pssDuration, long now) { 916 final ProcessRecord proc = profile.mApp; 917 EventLogTags.writeAmPss( 918 profile.getPid(), proc.uid, proc.processName, pss * 1024, uss * 1024, 919 swapPss * 1024, rss * 1024, statType, procState, pssDuration); 920 profile.setLastPssTime(now); 921 profile.addPss(pss, uss, rss, true, statType, pssDuration); 922 if (DEBUG_PSS) { 923 Slog.d(TAG_PSS, 924 "pss of " + proc.toShortString() + ": " + pss 925 + " lastPss=" + profile.getLastPss() 926 + " state=" + ProcessList.makeProcStateString(procState)); 927 } 928 if (profile.getInitialIdlePssOrRss() == 0) { 929 profile.setInitialIdlePssOrRss(pss); 930 } 931 profile.setLastPss(pss); 932 profile.setLastSwapPss(swapPss); 933 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 934 profile.setLastCachedPss(pss); 935 profile.setLastCachedSwapPss(swapPss); 936 } 937 profile.setLastRss(rss); 938 939 final SparseArray<Pair<Long, String>> watchUids = 940 mMemWatchProcesses.getMap().get(proc.processName); 941 Long check = null; 942 if (watchUids != null) { 943 Pair<Long, String> val = watchUids.get(proc.uid); 944 if (val == null) { 945 val = watchUids.get(0); 946 } 947 if (val != null) { 948 check = val.first; 949 } 950 } 951 if (check != null) { 952 if ((pss * 1024) >= check && profile.getThread() != null 953 && mMemWatchDumpProcName == null) { 954 if (Build.IS_DEBUGGABLE || proc.isDebuggable()) { 955 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting"); 956 startHeapDumpLPf(profile, false); 957 } else { 958 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check 959 + ", but debugging not enabled"); 960 } 961 } 962 } 963 } 964 965 /** 966 * Record new RSS sample for a process. 967 * 968 * This method is analogous to recordPssSampleLPf() and is intended to be used as a replacement 969 * if Flags.removeAppProfilerPssCollection() is enabled. Functionally, this differs in that PSS, 970 * SwapPss, and USS are no longer collected and reported. 971 * 972 * This method will also poll PSS if the app has requested that a heap dump be taken if its PSS 973 * reaches some threshold set with ActivityManager.setWatchHeapLimit(). 974 */ 975 @GuardedBy("mProfilerLock") recordRssSampleLPf(ProcessProfileRecord profile, int procState, long rss, int statType, long rssDuration, long now)976 private void recordRssSampleLPf(ProcessProfileRecord profile, int procState, long rss, 977 int statType, long rssDuration, long now) { 978 final ProcessRecord proc = profile.mApp; 979 // TODO(b/296454553): writeAmPss needs to be renamed to writeAmRss, and the zeroed out 980 // fields need to be removed. This will be updated once the flag is fully rolled out to 981 // avoid churn in the .logtags file, which has a mapping of IDs to tags (and is also 982 // technically deprecated). 983 EventLogTags.writeAmPss( 984 profile.getPid(), proc.uid, proc.processName, /* pss = */ 0, /* uss = */ 0, 985 /* swapPss = */ 0, rss * 1024, statType, procState, rssDuration); 986 profile.setLastPssTime(now); 987 // The PSS here is emitted in logs, so we can zero it out instead of subbing in RSS. 988 profile.addPss(/* pss = */ 0, /* uss = */ 0, rss, true, statType, rssDuration); 989 if (DEBUG_RSS) { 990 Slog.d(TAG_RSS, 991 "rss of " + proc.toShortString() + ": " + rss 992 + " lastRss=" + profile.getLastRss() 993 + " state=" + ProcessList.makeProcStateString(procState)); 994 } 995 if (profile.getInitialIdlePssOrRss() == 0) { 996 profile.setInitialIdlePssOrRss(rss); 997 } 998 profile.setLastRss(rss); 999 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1000 profile.setLastCachedRss(rss); 1001 } 1002 1003 final SparseArray<Pair<Long, String>> watchUids = 1004 mMemWatchProcesses.getMap().get(proc.processName); 1005 Long check = null; 1006 if (watchUids != null) { 1007 Pair<Long, String> val = watchUids.get(proc.uid); 1008 if (val == null) { 1009 val = watchUids.get(0); 1010 } 1011 if (val != null) { 1012 check = val.first; 1013 } 1014 } 1015 1016 if (check != null) { 1017 long pss = Debug.getPss(profile.getPid(), null, null); 1018 if ((pss * 1024) >= check && profile.getThread() != null 1019 && mMemWatchDumpProcName == null) { 1020 if (Build.IS_DEBUGGABLE || proc.isDebuggable()) { 1021 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting"); 1022 startHeapDumpLPf(profile, false); 1023 } else { 1024 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check 1025 + ", but debugging not enabled"); 1026 } 1027 } 1028 } 1029 } 1030 1031 private final class RecordPssRunnable implements Runnable { 1032 private final ProcessProfileRecord mProfile; 1033 private final Uri mDumpUri; 1034 private final ContentResolver mContentResolver; 1035 RecordPssRunnable(ProcessProfileRecord profile, Uri dumpUri, ContentResolver contentResolver)1036 RecordPssRunnable(ProcessProfileRecord profile, Uri dumpUri, 1037 ContentResolver contentResolver) { 1038 mProfile = profile; 1039 mDumpUri = dumpUri; 1040 mContentResolver = contentResolver; 1041 } 1042 1043 @Override run()1044 public void run() { 1045 try (ParcelFileDescriptor fd = mContentResolver.openFileDescriptor(mDumpUri, "rw")) { 1046 IApplicationThread thread = mProfile.getThread(); 1047 if (thread != null) { 1048 try { 1049 if (DEBUG_PSS) { 1050 Slog.d(TAG_PSS, "Requesting dump heap from " 1051 + mProfile.mApp + " to " + mDumpUri.getPath()); 1052 } 1053 thread.dumpHeap(/* managed= */ true, 1054 /* mallocInfo= */ false, 1055 /* runGc= */ false, 1056 /* dumpbitmaps= */ null, 1057 mDumpUri.getPath(), fd, 1058 /* finishCallback= */ null); 1059 } catch (RemoteException e) { 1060 } 1061 } 1062 } catch (IOException e) { 1063 Slog.e(TAG, "Failed to dump heap", e); 1064 // Need to clear the heap dump variables, otherwise no further heap dumps will be 1065 // attempted. 1066 abortHeapDump(mProfile.mApp.processName); 1067 } 1068 } 1069 } 1070 1071 @GuardedBy("mProfilerLock") startHeapDumpLPf(ProcessProfileRecord profile, boolean isUserInitiated)1072 void startHeapDumpLPf(ProcessProfileRecord profile, boolean isUserInitiated) { 1073 final ProcessRecord proc = profile.mApp; 1074 mMemWatchDumpProcName = proc.processName; 1075 mMemWatchDumpUri = makeHeapDumpUri(proc.processName); 1076 mMemWatchDumpPid = profile.getPid(); 1077 mMemWatchDumpUid = proc.uid; 1078 mMemWatchIsUserInitiated = isUserInitiated; 1079 Context ctx; 1080 try { 1081 ctx = mService.mContext.createPackageContextAsUser("android", 0, 1082 UserHandle.getUserHandleForUid(mMemWatchDumpUid)); 1083 } catch (NameNotFoundException e) { 1084 throw new RuntimeException("android package not found."); 1085 } 1086 BackgroundThread.getHandler().post( 1087 new RecordPssRunnable(profile, mMemWatchDumpUri, ctx.getContentResolver())); 1088 } 1089 dumpHeapFinished(String path, int callerPid)1090 void dumpHeapFinished(String path, int callerPid) { 1091 synchronized (mProfilerLock) { 1092 if (callerPid != mMemWatchDumpPid) { 1093 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid() 1094 + " does not match last pid " + mMemWatchDumpPid); 1095 return; 1096 } 1097 if (mMemWatchDumpUri == null || !mMemWatchDumpUri.getPath().equals(path)) { 1098 Slog.w(TAG, "dumpHeapFinished: Calling path " + path 1099 + " does not match last path " + mMemWatchDumpUri); 1100 return; 1101 } 1102 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path); 1103 mService.mHandler.sendEmptyMessage( 1104 ActivityManagerService.POST_DUMP_HEAP_NOTIFICATION_MSG); 1105 1106 // Forced gc to clean up the remnant hprof fd. 1107 Runtime.getRuntime().gc(); 1108 } 1109 } 1110 handlePostDumpHeapNotification()1111 void handlePostDumpHeapNotification() { 1112 final String procName; 1113 final int uid; 1114 final long memLimit; 1115 final String reportPackage; 1116 final boolean isUserInitiated; 1117 synchronized (mProfilerLock) { 1118 uid = mMemWatchDumpUid; 1119 procName = mMemWatchDumpProcName; 1120 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid); 1121 if (val == null) { 1122 val = mMemWatchProcesses.get(procName, 0); 1123 } 1124 if (val != null) { 1125 memLimit = val.first; 1126 reportPackage = val.second; 1127 } else { 1128 memLimit = 0; 1129 reportPackage = null; 1130 } 1131 isUserInitiated = mMemWatchIsUserInitiated; 1132 1133 mMemWatchDumpUri = null; 1134 mMemWatchDumpProcName = null; 1135 mMemWatchDumpPid = -1; 1136 mMemWatchDumpUid = -1; 1137 } 1138 if (procName == null) { 1139 return; 1140 } 1141 1142 if (DEBUG_PSS) { 1143 Slog.d(TAG_PSS, "Showing dump heap notification from " + procName + "/" + uid); 1144 } 1145 1146 Intent dumpFinishedIntent = new Intent(ACTION_HEAP_DUMP_FINISHED); 1147 // Send this only to the Shell package. 1148 dumpFinishedIntent.setPackage("com.android.shell"); 1149 dumpFinishedIntent.putExtra(Intent.EXTRA_UID, uid); 1150 dumpFinishedIntent.putExtra(EXTRA_HEAP_DUMP_IS_USER_INITIATED, isUserInitiated); 1151 dumpFinishedIntent.putExtra(EXTRA_HEAP_DUMP_SIZE_BYTES, memLimit); 1152 dumpFinishedIntent.putExtra(EXTRA_HEAP_DUMP_REPORT_PACKAGE, reportPackage); 1153 dumpFinishedIntent.putExtra(EXTRA_HEAP_DUMP_PROCESS_NAME, procName); 1154 1155 mService.mContext.sendBroadcastAsUser(dumpFinishedIntent, 1156 UserHandle.getUserHandleForUid(uid)); 1157 } 1158 setDumpHeapDebugLimit(String processName, int uid, long maxMemSize, String reportPackage)1159 void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize, 1160 String reportPackage) { 1161 synchronized (mProfilerLock) { 1162 if (maxMemSize > 0) { 1163 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage)); 1164 } else { 1165 if (uid != 0) { 1166 mMemWatchProcesses.remove(processName, uid); 1167 } else { 1168 mMemWatchProcesses.getMap().remove(processName); 1169 } 1170 } 1171 } 1172 } 1173 1174 /** Clear the currently executing heap dump variables so a new heap dump can be started. */ abortHeapDump(String procName)1175 private void abortHeapDump(String procName) { 1176 Message msg = mService.mHandler.obtainMessage(ActivityManagerService.ABORT_DUMPHEAP_MSG); 1177 msg.obj = procName; 1178 mService.mHandler.sendMessage(msg); 1179 } 1180 handleAbortDumpHeap(String procName)1181 void handleAbortDumpHeap(String procName) { 1182 if (procName != null) { 1183 synchronized (mProfilerLock) { 1184 if (procName.equals(mMemWatchDumpProcName)) { 1185 mMemWatchDumpProcName = null; 1186 mMemWatchDumpUri = null; 1187 mMemWatchDumpPid = -1; 1188 mMemWatchDumpUid = -1; 1189 } 1190 } 1191 } 1192 } 1193 1194 /** @hide */ makeHeapDumpUri(String procName)1195 private static Uri makeHeapDumpUri(String procName) { 1196 return Uri.parse("content://com.android.shell.heapdump/" + procName + "_javaheap.bin"); 1197 } 1198 1199 /** 1200 * Schedule PSS collection of a process. 1201 */ 1202 @GuardedBy("mProfilerLock") requestPssLPf(ProcessProfileRecord profile, int procState)1203 private boolean requestPssLPf(ProcessProfileRecord profile, int procState) { 1204 if (mPendingPssOrRssProfiles.contains(profile)) { 1205 return false; 1206 } 1207 if (mPendingPssOrRssProfiles.size() == 0) { 1208 final long deferral = (mPssDeferralTime > 0 && mActivityStartingNesting.get() > 0) 1209 ? mPssDeferralTime : 0; 1210 if (DEBUG_PSS && deferral > 0) { 1211 Slog.d(TAG_PSS, "requestPssLPf() deferring PSS request by " 1212 + deferral + " ms"); 1213 } 1214 mBgHandler.sendEmptyMessageDelayed(BgHandler.COLLECT_PSS_BG_MSG, deferral); 1215 } 1216 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + profile.mApp); 1217 profile.setPssProcState(procState); 1218 profile.setPssStatType(ProcessStats.ADD_PSS_INTERNAL_SINGLE); 1219 mPendingPssOrRssProfiles.add(profile); 1220 return true; 1221 } 1222 1223 /** 1224 * Re-defer a posted PSS collection pass, if one exists. Assumes deferral is 1225 * currently active policy when called. 1226 */ 1227 @GuardedBy("mProfilerLock") deferPssIfNeededLPf()1228 private void deferPssIfNeededLPf() { 1229 if (mPendingPssOrRssProfiles.size() > 0) { 1230 mBgHandler.removeMessages(BgHandler.COLLECT_PSS_BG_MSG); 1231 mBgHandler.sendEmptyMessageDelayed(BgHandler.COLLECT_PSS_BG_MSG, mPssDeferralTime); 1232 } 1233 } 1234 deferPssForActivityStart()1235 private void deferPssForActivityStart() { 1236 if (mPssDeferralTime > 0) { 1237 if (DEBUG_PSS) { 1238 Slog.d(TAG_PSS, "Deferring PSS collection for activity start"); 1239 } 1240 synchronized (mProfilerLock) { 1241 deferPssIfNeededLPf(); 1242 } 1243 mActivityStartingNesting.getAndIncrement(); 1244 mBgHandler.sendEmptyMessageDelayed(BgHandler.STOP_DEFERRING_PSS_MSG, mPssDeferralTime); 1245 } 1246 } 1247 stopDeferPss()1248 private void stopDeferPss() { 1249 final int nesting = mActivityStartingNesting.decrementAndGet(); 1250 if (nesting <= 0) { 1251 if (DEBUG_PSS) { 1252 Slog.d(TAG_PSS, "PSS activity start deferral interval ended; now " 1253 + nesting); 1254 } 1255 if (nesting < 0) { 1256 Slog.wtf(TAG, "Activity start nesting undercount!"); 1257 mActivityStartingNesting.incrementAndGet(); 1258 } 1259 } else { 1260 if (DEBUG_PSS) { 1261 Slog.d(TAG_PSS, "Still deferring PSS, nesting=" + nesting); 1262 } 1263 } 1264 } 1265 1266 /** 1267 * Schedule PSS collection of all processes. 1268 */ 1269 @GuardedBy("mProcLock") requestPssAllProcsLPr(long now, boolean always, boolean memLowered)1270 void requestPssAllProcsLPr(long now, boolean always, boolean memLowered) { 1271 synchronized (mProfilerLock) { 1272 if (!always) { 1273 if (now < (mLastFullPssTime 1274 + (memLowered ? mService.mConstants.FULL_PSS_LOWERED_INTERVAL 1275 : mService.mConstants.FULL_PSS_MIN_INTERVAL))) { 1276 return; 1277 } 1278 } 1279 if (DEBUG_PSS) { 1280 Slog.d(TAG_PSS, "Requesting pss of all procs! memLowered=" + memLowered); 1281 } 1282 mLastFullPssTime = now; 1283 mFullPssOrRssPending = true; 1284 for (int i = mPendingPssOrRssProfiles.size() - 1; i >= 0; i--) { 1285 mPendingPssOrRssProfiles.get(i).abortNextPssTime(); 1286 } 1287 mPendingPssOrRssProfiles.ensureCapacity(mService.mProcessList.getLruSizeLOSP()); 1288 mPendingPssOrRssProfiles.clear(); 1289 mService.mProcessList.forEachLruProcessesLOSP(false, app -> { 1290 final ProcessProfileRecord profile = app.mProfile; 1291 if (profile.getThread() == null 1292 || profile.getSetProcState() == PROCESS_STATE_NONEXISTENT) { 1293 return; 1294 } 1295 final long lastStateTime = profile.getLastStateTime(); 1296 if (memLowered || (always 1297 && now > lastStateTime + ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 1298 || now > (lastStateTime + ProcessList.PSS_ALL_INTERVAL)) { 1299 profile.setPssProcState(profile.getSetProcState()); 1300 profile.setPssStatType(always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL 1301 : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM); 1302 updateNextPssTimeLPf(profile.getSetProcState(), profile, now, true); 1303 mPendingPssOrRssProfiles.add(profile); 1304 } 1305 }); 1306 if (!mBgHandler.hasMessages(BgHandler.COLLECT_PSS_BG_MSG)) { 1307 mBgHandler.sendEmptyMessage(BgHandler.COLLECT_PSS_BG_MSG); 1308 } 1309 } 1310 } 1311 setTestPssMode(boolean enabled)1312 void setTestPssMode(boolean enabled) { 1313 synchronized (mProcLock) { 1314 mTestPssOrRssMode = enabled; 1315 if (enabled) { 1316 // Whenever we enable the mode, we want to take a snapshot all of current 1317 // process mem use. 1318 requestPssAllProcsLPr(SystemClock.uptimeMillis(), true, true); 1319 } 1320 } 1321 } 1322 getTestPssMode()1323 boolean getTestPssMode() { 1324 return mTestPssOrRssMode; 1325 } 1326 1327 @GuardedBy("mService") getLastMemoryLevelLocked()1328 @MemFactor int getLastMemoryLevelLocked() { 1329 if (mMemFactorOverride != ADJ_MEM_FACTOR_NOTHING) { 1330 return mMemFactorOverride; 1331 } 1332 return mLastMemoryLevel; 1333 } 1334 1335 @GuardedBy("mService") isLastMemoryLevelNormal()1336 boolean isLastMemoryLevelNormal() { 1337 if (mMemFactorOverride != ADJ_MEM_FACTOR_NOTHING) { 1338 return mMemFactorOverride <= ADJ_MEM_FACTOR_NORMAL; 1339 } 1340 return mLastMemoryLevel <= ADJ_MEM_FACTOR_NORMAL; 1341 } 1342 1343 @GuardedBy("mProcLock") updateLowRamTimestampLPr(long now)1344 void updateLowRamTimestampLPr(long now) { 1345 mLowRamTimeSinceLastIdle = 0; 1346 if (mLowRamStartTime != 0) { 1347 mLowRamStartTime = now; 1348 } 1349 } 1350 1351 @GuardedBy("mService") setAllowLowerMemLevelLocked(boolean allowLowerMemLevel)1352 void setAllowLowerMemLevelLocked(boolean allowLowerMemLevel) { 1353 mAllowLowerMemLevel = allowLowerMemLevel; 1354 } 1355 1356 @GuardedBy("mService") setMemFactorOverrideLocked(@emFactor int factor)1357 void setMemFactorOverrideLocked(@MemFactor int factor) { 1358 mMemFactorOverride = factor; 1359 mService.mProcessStateController.setIsLastMemoryLevelNormal(isLastMemoryLevelNormal()); 1360 } 1361 1362 @GuardedBy({"mService", "mProcLock"}) updateLowMemStateLSP(int numCached, int numEmpty, int numTrimming, long now)1363 void updateLowMemStateLSP(int numCached, int numEmpty, int numTrimming, long now) { 1364 int memFactor; 1365 if (mLowMemDetector != null && mLowMemDetector.isAvailable()) { 1366 memFactor = mLowMemDetector.getMemFactor(); 1367 } else { 1368 // Now determine the memory trimming level of background processes. 1369 // Unfortunately we need to start at the back of the list to do this 1370 // properly. We only do this if the number of background apps we 1371 // are managing to keep around is less than half the maximum we desire; 1372 // if we are keeping a good number around, we'll let them use whatever 1373 // memory they want. 1374 if (numCached <= mService.mConstants.CUR_TRIM_CACHED_PROCESSES 1375 && numEmpty <= mService.mConstants.CUR_TRIM_EMPTY_PROCESSES) { 1376 final int numCachedAndEmpty = numCached + numEmpty; 1377 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 1378 memFactor = ADJ_MEM_FACTOR_CRITICAL; 1379 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 1380 memFactor = ADJ_MEM_FACTOR_LOW; 1381 } else { 1382 memFactor = ADJ_MEM_FACTOR_MODERATE; 1383 } 1384 } else { 1385 memFactor = ADJ_MEM_FACTOR_NORMAL; 1386 } 1387 } 1388 // We always allow the memory level to go up (better). We only allow it to go 1389 // down if we are in a state where that is allowed, *and* the total number of processes 1390 // has gone down since last time. 1391 if (DEBUG_OOM_ADJ) { 1392 Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor + " override=" + mMemFactorOverride 1393 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel 1394 + " numProcs=" + mService.mProcessList.getLruSizeLOSP() 1395 + " last=" + mLastNumProcesses); 1396 } 1397 boolean override; 1398 if (override = (mMemFactorOverride != ADJ_MEM_FACTOR_NOTHING)) { 1399 memFactor = mMemFactorOverride; 1400 } 1401 if (memFactor > mLastMemoryLevel) { 1402 if (!override && (!mAllowLowerMemLevel 1403 || mService.mProcessList.getLruSizeLOSP() >= mLastNumProcesses)) { 1404 memFactor = mLastMemoryLevel; 1405 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!"); 1406 } 1407 } 1408 if (memFactor != mLastMemoryLevel) { 1409 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel); 1410 FrameworkStatsLog.write(FrameworkStatsLog.MEMORY_FACTOR_STATE_CHANGED, memFactor); 1411 mBgHandler.obtainMessage(BgHandler.MEMORY_PRESSURE_CHANGED, mLastMemoryLevel, memFactor) 1412 .sendToTarget(); 1413 } 1414 1415 mCachedAppsWatermarkData.updateCachedAppsHighWatermarkIfNecessaryLocked( 1416 numCached + numEmpty, now); 1417 boolean allChanged; 1418 int trackerMemFactor; 1419 synchronized (mService.mProcessStats.mLock) { 1420 allChanged = mService.mProcessStats.setMemFactorLocked(memFactor, 1421 mService.mAtmInternal == null || !mService.mAtmInternal.isSleeping(), 1422 SystemClock.uptimeMillis() /* re-acquire the time within the lock */); 1423 trackerMemFactor = mService.mProcessStats.getMemFactorLocked(); 1424 } 1425 1426 mLastMemoryLevel = memFactor; 1427 mService.mProcessStateController.setIsLastMemoryLevelNormal(isLastMemoryLevelNormal()); 1428 mLastNumProcesses = mService.mProcessList.getLruSizeLOSP(); 1429 1430 // Dispatch UI_HIDDEN to processes that need it 1431 mService.mProcessList.forEachLruProcessesLOSP( 1432 true, 1433 app -> { 1434 final ProcessProfileRecord profile = app.mProfile; 1435 final IApplicationThread thread; 1436 final ProcessStateRecord state = app.mState; 1437 if (state.hasProcStateChanged()) { 1438 state.setProcStateChanged(false); 1439 } 1440 int procState = app.mState.getCurProcState(); 1441 if (((procState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 1442 && procState 1443 < ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) 1444 || app.mState.isSystemNoUi()) 1445 && app.mProfile.hasPendingUiClean()) { 1446 // If this application is now in the background and it 1447 // had done UI, then give it the special trim level to 1448 // have it free UI resources. 1449 if ((thread = app.getThread()) != null) { 1450 try { 1451 thread.scheduleTrimMemory( 1452 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 1453 app.mProfile.setPendingUiClean(false); 1454 } catch (RemoteException e) { 1455 1456 } 1457 } 1458 } 1459 }); 1460 } 1461 1462 @GuardedBy({"mService", "mProcLock"}) trimMemoryUiHiddenIfNecessaryLSP(ProcessRecord app)1463 private void trimMemoryUiHiddenIfNecessaryLSP(ProcessRecord app) { 1464 if ((app.mState.getCurProcState() >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 1465 || app.mState.isSystemNoUi()) && app.mProfile.hasPendingUiClean()) { 1466 // If this application is now in the background and it 1467 // had done UI, then give it the special trim level to 1468 // have it free UI resources. 1469 scheduleTrimMemoryLSP(app, ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN, 1470 "Trimming memory of bg-ui "); 1471 app.mProfile.setPendingUiClean(false); 1472 } 1473 } 1474 1475 @GuardedBy({"mService", "mProcLock"}) scheduleTrimMemoryLSP(ProcessRecord app, int level, String msg)1476 private void scheduleTrimMemoryLSP(ProcessRecord app, int level, String msg) { 1477 IApplicationThread thread; 1478 if (app.mProfile.getTrimMemoryLevel() < level && (thread = app.getThread()) != null) { 1479 try { 1480 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) { 1481 Slog.v(TAG_OOM_ADJ, msg + app.processName + " to " + level); 1482 } 1483 mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(app, 1484 CachedAppOptimizer.UNFREEZE_REASON_TRIM_MEMORY); 1485 thread.scheduleTrimMemory(level); 1486 } catch (RemoteException e) { 1487 } 1488 } 1489 } 1490 1491 @GuardedBy("mProcLock") getLowRamTimeSinceIdleLPr(long now)1492 long getLowRamTimeSinceIdleLPr(long now) { 1493 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now - mLowRamStartTime) : 0); 1494 } 1495 1496 /** 1497 * Ask a given process to GC right now. 1498 */ 1499 @GuardedBy("mProfilerLock") performAppGcLPf(ProcessRecord app)1500 private void performAppGcLPf(ProcessRecord app) { 1501 try { 1502 final ProcessProfileRecord profile = app.mProfile; 1503 profile.setLastRequestedGc(SystemClock.uptimeMillis()); 1504 IApplicationThread thread = profile.getThread(); 1505 if (thread != null) { 1506 if (profile.getReportLowMemory()) { 1507 profile.setReportLowMemory(false); 1508 thread.scheduleLowMemory(); 1509 } else { 1510 thread.processInBackground(); 1511 } 1512 } 1513 } catch (Exception e) { 1514 // whatever. 1515 } 1516 } 1517 1518 /** 1519 * Perform GCs on all processes that are waiting for it, but only 1520 * if things are idle. 1521 */ 1522 @GuardedBy("mProfilerLock") performAppGcsLPf()1523 private void performAppGcsLPf() { 1524 if (mProcessesToGc.size() <= 0) { 1525 return; 1526 } 1527 while (mProcessesToGc.size() > 0) { 1528 final ProcessRecord proc = mProcessesToGc.remove(0); 1529 final ProcessProfileRecord profile = proc.mProfile; 1530 if (profile.getCurRawAdj() > ProcessList.PERCEPTIBLE_APP_ADJ 1531 || profile.getReportLowMemory()) { 1532 if ((profile.getLastRequestedGc() + mService.mConstants.GC_MIN_INTERVAL) 1533 <= SystemClock.uptimeMillis()) { 1534 // To avoid spamming the system, we will GC processes one 1535 // at a time, waiting a few seconds between each. 1536 performAppGcLPf(proc); 1537 scheduleAppGcsLPf(); 1538 return; 1539 } else { 1540 // It hasn't been long enough since we last GCed this 1541 // process... put it in the list to wait for its time. 1542 addProcessToGcListLPf(proc); 1543 break; 1544 } 1545 } 1546 } 1547 1548 scheduleAppGcsLPf(); 1549 } 1550 1551 /** 1552 * If all looks good, perform GCs on all processes waiting for them. 1553 */ 1554 @GuardedBy("mService") performAppGcsIfAppropriateLocked()1555 final void performAppGcsIfAppropriateLocked() { 1556 synchronized (mProfilerLock) { 1557 if (mService.canGcNowLocked()) { 1558 performAppGcsLPf(); 1559 return; 1560 } 1561 // Still not idle, wait some more. 1562 scheduleAppGcsLPf(); 1563 } 1564 } 1565 1566 /** 1567 * Schedule the execution of all pending app GCs. 1568 */ 1569 @GuardedBy("mProfilerLock") scheduleAppGcsLPf()1570 final void scheduleAppGcsLPf() { 1571 mService.mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 1572 1573 if (mProcessesToGc.size() > 0) { 1574 // Schedule a GC for the time to the next process. 1575 ProcessRecord proc = mProcessesToGc.get(0); 1576 Message msg = mService.mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 1577 1578 long when = proc.mProfile.getLastRequestedGc() + mService.mConstants.GC_MIN_INTERVAL; 1579 long now = SystemClock.uptimeMillis(); 1580 if (when < (now + mService.mConstants.GC_TIMEOUT)) { 1581 when = now + mService.mConstants.GC_TIMEOUT; 1582 } 1583 mService.mHandler.sendMessageAtTime(msg, when); 1584 } 1585 } 1586 1587 /** 1588 * Add a process to the array of processes waiting to be GCed. Keeps the 1589 * list in sorted order by the last GC time. The process can't already be 1590 * on the list. 1591 */ 1592 @GuardedBy("mProfilerLock") addProcessToGcListLPf(ProcessRecord proc)1593 private void addProcessToGcListLPf(ProcessRecord proc) { 1594 boolean added = false; 1595 for (int i = mProcessesToGc.size() - 1; i >= 0; i--) { 1596 if (mProcessesToGc.get(i).mProfile.getLastRequestedGc() 1597 < proc.mProfile.getLastRequestedGc()) { 1598 added = true; 1599 mProcessesToGc.add(i + 1, proc); 1600 break; 1601 } 1602 } 1603 if (!added) { 1604 mProcessesToGc.add(0, proc); 1605 } 1606 } 1607 1608 @GuardedBy("mService") doLowMemReportIfNeededLocked(ProcessRecord dyingProc)1609 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 1610 // If there are no longer any background processes running, 1611 // and the app that died was not running instrumentation, 1612 // then tell everyone we are now low on memory. 1613 if (!mService.mProcessList.haveBackgroundProcessLOSP()) { 1614 boolean doReport = Build.IS_DEBUGGABLE; 1615 final long now = SystemClock.uptimeMillis(); 1616 if (doReport) { 1617 if (now < (mLastMemUsageReportTime + 5 * 60 * 1000)) { 1618 doReport = false; 1619 } else { 1620 mLastMemUsageReportTime = now; 1621 } 1622 } 1623 final int lruSize = mService.mProcessList.getLruSizeLOSP(); 1624 final ArrayList<ProcessMemInfo> memInfos = doReport 1625 ? new ArrayList<ProcessMemInfo>(lruSize) : null; 1626 EventLogTags.writeAmLowMemory(lruSize); 1627 mService.mProcessList.forEachLruProcessesLOSP(false, rec -> { 1628 if (rec == dyingProc || rec.getThread() == null) { 1629 return; 1630 } 1631 final ProcessStateRecord state = rec.mState; 1632 if (memInfos != null) { 1633 memInfos.add(new ProcessMemInfo(rec.processName, rec.getPid(), 1634 state.getSetAdj(), state.getSetProcState(), 1635 state.getAdjType(), state.makeAdjReason())); 1636 } 1637 final ProcessProfileRecord profile = rec.mProfile; 1638 if ((profile.getLastLowMemory() + mService.mConstants.GC_MIN_INTERVAL) <= now) { 1639 // The low memory report is overriding any current 1640 // state for a GC request. Make sure to do 1641 // heavy/important/visible/foreground processes first. 1642 synchronized (mProfilerLock) { 1643 if (state.getSetAdj() <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 1644 profile.setLastRequestedGc(0); 1645 } else { 1646 profile.setLastRequestedGc(profile.getLastLowMemory()); 1647 } 1648 profile.setReportLowMemory(true); 1649 profile.setLastLowMemory(now); 1650 mProcessesToGc.remove(rec); 1651 addProcessToGcListLPf(rec); 1652 } 1653 } 1654 }); 1655 if (doReport) { 1656 Message msg = mService.mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 1657 mService.mHandler.sendMessage(msg); 1658 } 1659 } 1660 synchronized (mProfilerLock) { 1661 scheduleAppGcsLPf(); 1662 } 1663 } 1664 reportMemUsage(ArrayList<ProcessMemInfo> memInfos)1665 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 1666 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 1667 for (int i = 0, size = memInfos.size(); i < size; i++) { 1668 ProcessMemInfo mi = memInfos.get(i); 1669 infoMap.put(mi.pid, mi); 1670 } 1671 updateCpuStatsNow(); 1672 long[] memtrackTmp = new long[4]; 1673 long[] swaptrackTmp = new long[2]; 1674 // Get a list of Stats that have vsize > 0 1675 final List<ProcessCpuTracker.Stats> stats = getCpuStats(st -> st.vsize > 0); 1676 final int statsCount = stats.size(); 1677 long totalMemtrackGraphics = 0; 1678 long totalMemtrackGl = 0; 1679 for (int i = 0; i < statsCount; i++) { 1680 ProcessCpuTracker.Stats st = stats.get(i); 1681 long pss = Debug.getPss(st.pid, swaptrackTmp, memtrackTmp); 1682 if (pss > 0) { 1683 if (infoMap.indexOfKey(st.pid) < 0) { 1684 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1685 ProcessList.NATIVE_ADJ, -1, "native", null); 1686 mi.pss = pss; 1687 mi.swapPss = swaptrackTmp[1]; 1688 mi.memtrack = memtrackTmp[0]; 1689 totalMemtrackGraphics += memtrackTmp[1]; 1690 totalMemtrackGl += memtrackTmp[2]; 1691 memInfos.add(mi); 1692 } 1693 } 1694 } 1695 1696 long totalPss = 0; 1697 long totalSwapPss = 0; 1698 long totalMemtrack = 0; 1699 for (int i = 0, size = memInfos.size(); i < size; i++) { 1700 ProcessMemInfo mi = memInfos.get(i); 1701 if (mi.pss == 0) { 1702 mi.pss = Debug.getPss(mi.pid, swaptrackTmp, memtrackTmp); 1703 mi.swapPss = swaptrackTmp[1]; 1704 mi.memtrack = memtrackTmp[0]; 1705 totalMemtrackGraphics += memtrackTmp[1]; 1706 totalMemtrackGl += memtrackTmp[2]; 1707 } 1708 totalPss += mi.pss; 1709 totalSwapPss += mi.swapPss; 1710 totalMemtrack += mi.memtrack; 1711 } 1712 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1713 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1714 if (lhs.oomAdj != rhs.oomAdj) { 1715 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1716 } 1717 if (lhs.pss != rhs.pss) { 1718 return lhs.pss < rhs.pss ? 1 : -1; 1719 } 1720 return 0; 1721 } 1722 }); 1723 1724 StringBuilder tag = new StringBuilder(128); 1725 StringBuilder stack = new StringBuilder(128); 1726 tag.append("Low on memory -- "); 1727 appendMemBucket(tag, totalPss, "total", false); 1728 appendMemBucket(stack, totalPss, "total", true); 1729 1730 StringBuilder fullNativeBuilder = new StringBuilder(1024); 1731 StringBuilder shortNativeBuilder = new StringBuilder(1024); 1732 StringBuilder fullJavaBuilder = new StringBuilder(1024); 1733 1734 boolean firstLine = true; 1735 int lastOomAdj = Integer.MIN_VALUE; 1736 long extraNativeRam = 0; 1737 long extraNativeMemtrack = 0; 1738 long cachedPss = 0; 1739 for (int i = 0, size = memInfos.size(); i < size; i++) { 1740 ProcessMemInfo mi = memInfos.get(i); 1741 1742 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 1743 cachedPss += mi.pss; 1744 } 1745 1746 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1747 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1748 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1749 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1750 if (lastOomAdj != mi.oomAdj) { 1751 lastOomAdj = mi.oomAdj; 1752 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1753 tag.append(" / "); 1754 } 1755 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1756 if (firstLine) { 1757 stack.append(":"); 1758 firstLine = false; 1759 } 1760 stack.append("\n\t at "); 1761 } else { 1762 stack.append("$"); 1763 } 1764 } else { 1765 tag.append(" "); 1766 stack.append("$"); 1767 } 1768 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1769 appendMemBucket(tag, mi.pss, mi.name, false); 1770 } 1771 appendMemBucket(stack, mi.pss, mi.name, true); 1772 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1773 && ((i + 1) >= size || memInfos.get(i + 1).oomAdj != lastOomAdj)) { 1774 stack.append("("); 1775 for (int k = 0; k < DUMP_MEM_OOM_ADJ.length; k++) { 1776 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1777 stack.append(DUMP_MEM_OOM_LABEL[k]); 1778 stack.append(":"); 1779 stack.append(DUMP_MEM_OOM_ADJ[k]); 1780 } 1781 } 1782 stack.append(")"); 1783 } 1784 } 1785 1786 appendMemInfo(fullNativeBuilder, mi); 1787 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 1788 // The short form only has native processes that are >= 512K. 1789 if (mi.pss >= 512) { 1790 appendMemInfo(shortNativeBuilder, mi); 1791 } else { 1792 extraNativeRam += mi.pss; 1793 extraNativeMemtrack += mi.memtrack; 1794 } 1795 } else { 1796 // Short form has all other details, but if we have collected RAM 1797 // from smaller native processes let's dump a summary of that. 1798 if (extraNativeRam > 0) { 1799 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 1800 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 1801 shortNativeBuilder.append('\n'); 1802 extraNativeRam = 0; 1803 } 1804 appendMemInfo(fullJavaBuilder, mi); 1805 } 1806 } 1807 1808 fullJavaBuilder.append(" "); 1809 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 1810 fullJavaBuilder.append(": TOTAL"); 1811 if (totalMemtrack > 0) { 1812 fullJavaBuilder.append(" ("); 1813 fullJavaBuilder.append(stringifyKBSize(totalMemtrack)); 1814 fullJavaBuilder.append(" memtrack)"); 1815 } 1816 fullJavaBuilder.append("\n"); 1817 1818 MemInfoReader memInfo = new MemInfoReader(); 1819 memInfo.readMemInfo(); 1820 final long[] infos = memInfo.getRawInfo(); 1821 1822 StringBuilder memInfoBuilder = new StringBuilder(1024); 1823 Debug.getMemInfo(infos); 1824 memInfoBuilder.append(" MemInfo: "); 1825 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, "); 1826 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, "); 1827 memInfoBuilder.append(stringifyKBSize( 1828 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, "); 1829 memInfoBuilder.append(stringifyKBSize( 1830 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables "); 1831 memInfoBuilder.append(stringifyKBSize( 1832 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n"); 1833 memInfoBuilder.append(" "); 1834 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, "); 1835 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, "); 1836 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, "); 1837 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n"); 1838 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1839 memInfoBuilder.append(" ZRAM: "); 1840 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL])); 1841 memInfoBuilder.append(" RAM, "); 1842 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL])); 1843 memInfoBuilder.append(" swap total, "); 1844 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE])); 1845 memInfoBuilder.append(" swap free\n"); 1846 } 1847 final long[] ksm = getKsmInfo(); 1848 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 1849 || ksm[KSM_VOLATILE] != 0) { 1850 memInfoBuilder.append(" KSM: "); 1851 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING])); 1852 memInfoBuilder.append(" saved from shared "); 1853 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED])); 1854 memInfoBuilder.append("\n "); 1855 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED])); 1856 memInfoBuilder.append(" unshared; "); 1857 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE])); 1858 memInfoBuilder.append(" volatile\n"); 1859 } 1860 memInfoBuilder.append(" Free RAM: "); 1861 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb() 1862 + memInfo.getFreeSizeKb())); 1863 memInfoBuilder.append("\n"); 1864 long kernelUsed = memInfo.getKernelUsedSizeKb(); 1865 final long ionHeap = Debug.getIonHeapsSizeKb(); 1866 final long ionPool = Debug.getIonPoolsSizeKb(); 1867 final long dmabufMapped = Debug.getDmabufMappedSizeKb(); 1868 if (ionHeap >= 0 && ionPool >= 0) { 1869 final long ionUnmapped = ionHeap - dmabufMapped; 1870 memInfoBuilder.append(" ION: "); 1871 memInfoBuilder.append(stringifyKBSize(ionHeap + ionPool)); 1872 memInfoBuilder.append("\n"); 1873 kernelUsed += ionUnmapped; 1874 // Note: mapped ION memory is not accounted in PSS due to VM_PFNMAP flag being 1875 // set on ION VMAs, however it might be included by the memtrack HAL. 1876 // Replace memtrack HAL reported Graphics category with mapped dmabufs 1877 totalPss -= totalMemtrackGraphics; 1878 totalPss += dmabufMapped; 1879 } else { 1880 final long totalExportedDmabuf = Debug.getDmabufTotalExportedKb(); 1881 if (totalExportedDmabuf >= 0) { 1882 final long dmabufUnmapped = totalExportedDmabuf - dmabufMapped; 1883 memInfoBuilder.append("DMA-BUF: "); 1884 memInfoBuilder.append(stringifyKBSize(totalExportedDmabuf)); 1885 memInfoBuilder.append("\n"); 1886 // Account unmapped dmabufs as part of kernel memory allocations 1887 kernelUsed += dmabufUnmapped; 1888 // Replace memtrack HAL reported Graphics category with mapped dmabufs 1889 totalPss -= totalMemtrackGraphics; 1890 totalPss += dmabufMapped; 1891 } 1892 // These are included in the totalExportedDmabuf above and hence do not need to be added 1893 // to kernelUsed. 1894 final long totalExportedDmabufHeap = Debug.getDmabufHeapTotalExportedKb(); 1895 if (totalExportedDmabufHeap >= 0) { 1896 memInfoBuilder.append("DMA-BUF Heap: "); 1897 memInfoBuilder.append(stringifyKBSize(totalExportedDmabufHeap)); 1898 memInfoBuilder.append("\n"); 1899 } 1900 1901 final long totalDmabufHeapPool = Debug.getDmabufHeapPoolsSizeKb(); 1902 if (totalDmabufHeapPool >= 0) { 1903 memInfoBuilder.append("DMA-BUF Heaps pool: "); 1904 memInfoBuilder.append(stringifyKBSize(totalDmabufHeapPool)); 1905 memInfoBuilder.append("\n"); 1906 } 1907 } 1908 1909 final long gpuUsage = Debug.getGpuTotalUsageKb(); 1910 if (gpuUsage >= 0) { 1911 final long gpuPrivateUsage = Debug.getGpuPrivateMemoryKb(); 1912 if (gpuPrivateUsage >= 0) { 1913 final long gpuDmaBufUsage = gpuUsage - gpuPrivateUsage; 1914 memInfoBuilder.append(" GPU: "); 1915 memInfoBuilder.append(stringifyKBSize(gpuUsage)); 1916 memInfoBuilder.append(" ("); 1917 memInfoBuilder.append(stringifyKBSize(gpuDmaBufUsage)); 1918 memInfoBuilder.append(" dmabuf + "); 1919 memInfoBuilder.append(stringifyKBSize(gpuPrivateUsage)); 1920 memInfoBuilder.append(" private)\n"); 1921 // Replace memtrack HAL reported GL category with private GPU allocations and 1922 // account it as part of kernel memory allocations 1923 totalPss -= totalMemtrackGl; 1924 kernelUsed += gpuPrivateUsage; 1925 } else { 1926 memInfoBuilder.append(" GPU: "); 1927 memInfoBuilder.append(stringifyKBSize(gpuUsage)); 1928 memInfoBuilder.append("\n"); 1929 } 1930 1931 } 1932 memInfoBuilder.append(" Used RAM: "); 1933 memInfoBuilder.append(stringifyKBSize( 1934 totalPss - cachedPss + kernelUsed)); 1935 memInfoBuilder.append("\n"); 1936 1937 // Note: ION/DMA-BUF heap pools are reclaimable and hence, they are included as part of 1938 // memInfo.getCachedSizeKb(). 1939 memInfoBuilder.append(" Lost RAM: "); 1940 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb() 1941 - (totalPss - totalSwapPss) - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 1942 - kernelUsed - memInfo.getZramTotalSizeKb())); 1943 memInfoBuilder.append("\n"); 1944 Slog.i(TAG, "Low on memory:"); 1945 Slog.i(TAG, shortNativeBuilder.toString()); 1946 Slog.i(TAG, fullJavaBuilder.toString()); 1947 Slog.i(TAG, memInfoBuilder.toString()); 1948 1949 StringBuilder dropBuilder = new StringBuilder(1024); 1950 dropBuilder.append("Low on memory:"); 1951 dropBuilder.append(stack); 1952 dropBuilder.append('\n'); 1953 dropBuilder.append(fullNativeBuilder); 1954 dropBuilder.append(fullJavaBuilder); 1955 dropBuilder.append('\n'); 1956 dropBuilder.append(memInfoBuilder); 1957 dropBuilder.append('\n'); 1958 StringWriter catSw = new StringWriter(); 1959 synchronized (mService) { 1960 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1961 String[] emptyArgs = new String[] { }; 1962 catPw.println(); 1963 synchronized (mProcLock) { 1964 mService.mProcessList.dumpProcessesLSP(null, catPw, emptyArgs, 0, false, null, -1); 1965 } 1966 catPw.println(); 1967 mService.mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0, 1968 false, null).dumpLocked(); 1969 catPw.println(); 1970 mService.mAtmInternal.dump(DUMP_ACTIVITIES_CMD, null, catPw, emptyArgs, 0, false, false, 1971 null, INVALID_DISPLAY); 1972 catPw.flush(); 1973 } 1974 dropBuilder.append(catSw.toString()); 1975 FrameworkStatsLog.write(FrameworkStatsLog.LOW_MEM_REPORTED); 1976 mService.addErrorToDropBox("lowmem", null, "system_server", null, 1977 null, null, tag.toString(), dropBuilder.toString(), null, null, null, null, null, 1978 null); 1979 synchronized (mService) { 1980 long now = SystemClock.uptimeMillis(); 1981 if (mLastMemUsageReportTime < now) { 1982 mLastMemUsageReportTime = now; 1983 } 1984 } 1985 } 1986 1987 @GuardedBy("mService") handleMemoryPressureChangedLocked(@emFactor int oldMemFactor, @MemFactor int newMemFactor)1988 private void handleMemoryPressureChangedLocked(@MemFactor int oldMemFactor, 1989 @MemFactor int newMemFactor) { 1990 mService.mServices.rescheduleServiceRestartOnMemoryPressureIfNeededLocked( 1991 oldMemFactor, newMemFactor, "mem-pressure-event", SystemClock.uptimeMillis()); 1992 } 1993 1994 @GuardedBy("mProfilerLock") stopProfilerLPf(ProcessRecord proc, ProfilerInfo profilerInfo, int profileType)1995 private void stopProfilerLPf(ProcessRecord proc, ProfilerInfo profilerInfo, int profileType) { 1996 if (proc == null || proc == mProfileData.getProfileProc()) { 1997 proc = mProfileData.getProfileProc(); 1998 profileType = mProfileType; 1999 clearProfilerLPf(); 2000 } 2001 if (proc == null) { 2002 return; 2003 } 2004 final IApplicationThread thread = proc.mProfile.getThread(); 2005 if (thread == null) { 2006 return; 2007 } 2008 try { 2009 thread.profilerControl(false, profilerInfo, profileType); 2010 } catch (RemoteException e) { 2011 throw new IllegalStateException("Process disappeared"); 2012 } 2013 } 2014 2015 @GuardedBy("mProfilerLock") clearProfilerLPf()2016 void clearProfilerLPf() { 2017 if (mProfileData.getProfilerInfo() != null 2018 && mProfileData.getProfilerInfo().profileFd != null) { 2019 try { 2020 mProfileData.getProfilerInfo().profileFd.close(); 2021 } catch (IOException e) { 2022 } 2023 } 2024 mProfileData.setProfileApp(null); 2025 mProfileData.setProfileProc(null); 2026 mProfileData.setProfilerInfo(null); 2027 } 2028 2029 @GuardedBy("mProfilerLock") clearProfilerLPf(ProcessRecord app)2030 void clearProfilerLPf(ProcessRecord app) { 2031 if (mProfileData.getProfileProc() == null 2032 || mProfileData.getProfilerInfo() == null 2033 || mProfileData.getProfileProc() != app) { 2034 return; 2035 } 2036 clearProfilerLPf(); 2037 } 2038 2039 @GuardedBy("mProfilerLock") profileControlLPf(ProcessRecord proc, boolean start, ProfilerInfo profilerInfo, int profileType)2040 boolean profileControlLPf(ProcessRecord proc, boolean start, 2041 ProfilerInfo profilerInfo, int profileType) { 2042 try { 2043 if (start) { 2044 boolean needsFile = (profileType == ProfilerInfo.PROFILE_TYPE_REGULAR); 2045 stopProfilerLPf(null, null, 0); 2046 mService.setProfileApp(proc.info, proc.processName, profilerInfo, 2047 proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null, profileType); 2048 mProfileData.setProfileProc(proc); 2049 mProfileType = profileType; 2050 2051 ParcelFileDescriptor fd = null; 2052 if (needsFile) { 2053 fd = profilerInfo.profileFd; 2054 try { 2055 fd = fd.dup(); 2056 } catch (IOException e) { 2057 fd = null; 2058 } 2059 profilerInfo.profileFd = fd; 2060 } 2061 2062 proc.mProfile.getThread().profilerControl(start, profilerInfo, profileType); 2063 2064 if (needsFile) { 2065 fd = null; 2066 try { 2067 mProfileData.getProfilerInfo().profileFd.close(); 2068 } catch (IOException e) { 2069 } 2070 mProfileData.getProfilerInfo().profileFd = null; 2071 2072 if (proc.getPid() == mService.MY_PID) { 2073 // When profiling the system server itself, avoid closing the file 2074 // descriptor, as profilerControl will not create a copy. 2075 // Note: it is also not correct to just set profileFd to null, as the 2076 // whole ProfilerInfo instance is passed down! 2077 profilerInfo = null; 2078 } 2079 } 2080 } else { 2081 boolean mayNeedFile = (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD); 2082 if (profilerInfo != null && profilerInfo.profileFd != null) { 2083 ParcelFileDescriptor fd = profilerInfo.profileFd; 2084 try { 2085 if (mayNeedFile) { 2086 fd = fd.dup(); 2087 } else { 2088 fd.close(); 2089 } 2090 } catch (IOException e) { 2091 fd = null; 2092 } 2093 profilerInfo.profileFd = fd; 2094 } 2095 stopProfilerLPf(proc, profilerInfo, profileType); 2096 } 2097 2098 return true; 2099 } catch (RemoteException e) { 2100 throw new IllegalStateException("Process disappeared"); 2101 } finally { 2102 if (profilerInfo != null && profilerInfo.profileFd != null) { 2103 try { 2104 profilerInfo.profileFd.close(); 2105 } catch (IOException e) { 2106 } 2107 } 2108 } 2109 } 2110 2111 @GuardedBy("mProfilerLock") setProfileAppLPf(String processName, ProfilerInfo profilerInfo, int profileType)2112 void setProfileAppLPf(String processName, ProfilerInfo profilerInfo, int profileType) { 2113 mProfileData.setProfileApp(processName); 2114 2115 if (mProfileData.getProfilerInfo() != null) { 2116 if (mProfileData.getProfilerInfo().profileFd != null) { 2117 try { 2118 mProfileData.getProfilerInfo().profileFd.close(); 2119 } catch (IOException e) { 2120 } 2121 } 2122 } 2123 if (profilerInfo != null) { 2124 mProfileData.setProfilerInfo(new ProfilerInfo(profilerInfo)); 2125 } 2126 mProfileType = profileType; 2127 } 2128 2129 @GuardedBy("mProfilerLock") setProfileProcLPf(ProcessRecord proc)2130 void setProfileProcLPf(ProcessRecord proc) { 2131 mProfileData.setProfileProc(proc); 2132 } 2133 2134 @GuardedBy("mProfilerLock") setAgentAppLPf(@onNull String packageName, @Nullable String agent)2135 void setAgentAppLPf(@NonNull String packageName, @Nullable String agent) { 2136 if (agent == null) { 2137 if (mAppAgentMap != null) { 2138 mAppAgentMap.remove(packageName); 2139 if (mAppAgentMap.isEmpty()) { 2140 mAppAgentMap = null; 2141 } 2142 } 2143 } else { 2144 if (mAppAgentMap == null) { 2145 mAppAgentMap = new HashMap<>(); 2146 } 2147 if (mAppAgentMap.size() >= 100) { 2148 // Limit the size of the map, to avoid OOMEs. 2149 Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName 2150 + "/" + agent); 2151 return; 2152 } 2153 mAppAgentMap.put(packageName, agent); 2154 } 2155 } 2156 updateCpuStats()2157 void updateCpuStats() { 2158 final long now = SystemClock.uptimeMillis(); 2159 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2160 return; 2161 } 2162 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2163 synchronized (mProcessCpuThread) { 2164 mProcessCpuThread.notify(); 2165 } 2166 } 2167 } 2168 updateCpuStatsNow()2169 void updateCpuStatsNow() { 2170 final boolean monitorPhantomProcs = mService.mSystemReady && FeatureFlagUtils.isEnabled( 2171 mService.mContext, SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS); 2172 synchronized (mProcessCpuTracker) { 2173 mProcessCpuMutexFree.set(false); 2174 final long now = SystemClock.uptimeMillis(); 2175 boolean haveNewCpuStats = false; 2176 2177 if (MONITOR_CPU_USAGE 2178 && mLastCpuTime.get() < (now - MONITOR_CPU_MIN_TIME)) { 2179 mLastCpuTime.set(now); 2180 mProcessCpuTracker.update(); 2181 if (mProcessCpuTracker.hasGoodLastStats()) { 2182 haveNewCpuStats = true; 2183 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2184 //Slog.i(TAG, "Total CPU usage: " 2185 // + mProcessCpu.getTotalCpuPercent() + "%"); 2186 2187 // Slog the cpu usage if the property is set. 2188 if ("true".equals(SystemProperties.get("events.cpu"))) { 2189 int user = mProcessCpuTracker.getLastUserTime(); 2190 int system = mProcessCpuTracker.getLastSystemTime(); 2191 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2192 int irq = mProcessCpuTracker.getLastIrqTime(); 2193 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2194 int idle = mProcessCpuTracker.getLastIdleTime(); 2195 2196 int total = user + system + iowait + irq + softIrq + idle; 2197 if (total == 0) total = 1; 2198 2199 EventLogTags.writeCpu( 2200 ((user + system + iowait + irq + softIrq) * 100) / total, 2201 (user * 100) / total, 2202 (system * 100) / total, 2203 (iowait * 100) / total, 2204 (irq * 100) / total, 2205 (softIrq * 100) / total); 2206 } 2207 } 2208 } 2209 2210 if (monitorPhantomProcs && haveNewCpuStats) { 2211 mService.mPhantomProcessList.updateProcessCpuStatesLocked(mProcessCpuTracker); 2212 } 2213 2214 final BatteryStatsImpl bstats = mService.mBatteryStatsService.getActiveStatistics(); 2215 synchronized (bstats) { 2216 if (haveNewCpuStats) { 2217 if (bstats.startAddingCpuStatsLocked()) { 2218 int totalUTime = 0; 2219 int totalSTime = 0; 2220 final int statsCount = mProcessCpuTracker.countStats(); 2221 final long elapsedRealtime = SystemClock.elapsedRealtime(); 2222 final long uptime = SystemClock.uptimeMillis(); 2223 synchronized (mService.mPidsSelfLocked) { 2224 for (int i = 0; i < statsCount; i++) { 2225 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2226 if (!st.working) { 2227 continue; 2228 } 2229 ProcessRecord pr = mService.mPidsSelfLocked.get(st.pid); 2230 totalUTime += st.rel_utime; 2231 totalSTime += st.rel_stime; 2232 if (pr != null) { 2233 final ProcessProfileRecord profile = pr.mProfile; 2234 BatteryStatsImpl.Uid.Proc ps = profile.getCurProcBatteryStats(); 2235 if (ps == null || !ps.isActive()) { 2236 profile.setCurProcBatteryStats( 2237 ps = bstats.getProcessStatsLocked( 2238 pr.info.uid, pr.processName, 2239 elapsedRealtime, uptime)); 2240 } 2241 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 2242 final long curCpuTime = profile.mCurCpuTime.addAndGet( 2243 st.rel_utime + st.rel_stime); 2244 profile.mLastCpuTime.compareAndSet(0, curCpuTime); 2245 } else { 2246 BatteryStatsImpl.Uid.Proc ps = 2247 (BatteryStatsImpl.Uid.Proc) st.batteryStats; 2248 if (ps == null || !ps.isActive()) { 2249 st.batteryStats = ps = bstats.getProcessStatsLocked( 2250 st.uid, st.name, elapsedRealtime, uptime); 2251 } 2252 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 2253 } 2254 EventLogTags.writeAmCpu(st.pid, st.uid, st.baseName, 2255 st.rel_uptime, st.rel_utime, st.rel_stime); 2256 } 2257 } 2258 2259 final int userTime = mProcessCpuTracker.getLastUserTime(); 2260 final int systemTime = mProcessCpuTracker.getLastSystemTime(); 2261 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime(); 2262 final int irqTime = mProcessCpuTracker.getLastIrqTime(); 2263 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime(); 2264 final int idleTime = mProcessCpuTracker.getLastIdleTime(); 2265 bstats.addCpuStatsLocked(totalUTime, totalSTime, userTime, 2266 systemTime, iowaitTime, irqTime, softIrqTime, idleTime); 2267 bstats.finishAddingCpuStatsLocked(); 2268 } 2269 } 2270 2271 if (mLastWriteTime < (now - BATTERY_STATS_TIME)) { 2272 mLastWriteTime = now; 2273 mService.mBatteryStatsService.scheduleWriteToDisk(); 2274 } 2275 } 2276 } 2277 } 2278 getCpuTimeForPid(int pid)2279 long getCpuTimeForPid(int pid) { 2280 return mProcessCpuTracker.getCpuTimeForPid(pid); 2281 } 2282 getCpuDelayTimeForPid(int pid)2283 long getCpuDelayTimeForPid(int pid) { 2284 return mProcessCpuTracker.getCpuDelayTimeForPid(pid); 2285 } 2286 getCpuStats(Predicate<ProcessCpuTracker.Stats> predicate)2287 List<ProcessCpuTracker.Stats> getCpuStats(Predicate<ProcessCpuTracker.Stats> predicate) { 2288 synchronized (mProcessCpuTracker) { 2289 return mProcessCpuTracker.getStats(st -> predicate.test(st)); 2290 } 2291 } 2292 forAllCpuStats(Consumer<ProcessCpuTracker.Stats> consumer)2293 void forAllCpuStats(Consumer<ProcessCpuTracker.Stats> consumer) { 2294 synchronized (mProcessCpuTracker) { 2295 final int numOfStats = mProcessCpuTracker.countStats(); 2296 for (int i = 0; i < numOfStats; i++) { 2297 consumer.accept(mProcessCpuTracker.getStats(i)); 2298 } 2299 } 2300 } 2301 2302 private class ProcessCpuThread extends Thread { ProcessCpuThread(String name)2303 ProcessCpuThread(String name) { 2304 super(name); 2305 } 2306 2307 @Override run()2308 public void run() { 2309 synchronized (mProcessCpuTracker) { 2310 mProcessCpuInitLatch.countDown(); 2311 mProcessCpuTracker.init(); 2312 } 2313 while (true) { 2314 try { 2315 try { 2316 synchronized (this) { 2317 final long now = SystemClock.uptimeMillis(); 2318 long nextCpuDelay = (mLastCpuTime.get() + MONITOR_CPU_MAX_TIME) - now; 2319 long nextWriteDelay = (mLastWriteTime + BATTERY_STATS_TIME) - now; 2320 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2321 // + ", write delay=" + nextWriteDelay); 2322 if (nextWriteDelay < nextCpuDelay) { 2323 nextCpuDelay = nextWriteDelay; 2324 } 2325 if (nextCpuDelay > 0) { 2326 mProcessCpuMutexFree.set(true); 2327 this.wait(nextCpuDelay); 2328 } 2329 } 2330 } catch (InterruptedException e) { 2331 } 2332 updateCpuStatsNow(); 2333 } catch (Exception e) { 2334 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2335 } 2336 } 2337 } 2338 } 2339 2340 class CpuBinder extends Binder { 2341 private final PriorityDump.PriorityDumper mPriorityDumper = 2342 new PriorityDump.PriorityDumper() { 2343 @Override 2344 public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args, 2345 boolean asProto) { 2346 if (!DumpUtils.checkDumpAndUsageStatsPermission(mService.mContext, "cpuinfo", pw)) { 2347 return; 2348 } 2349 synchronized (mProcessCpuTracker) { 2350 if (asProto) { 2351 mProcessCpuTracker.dumpProto(fd); 2352 return; 2353 } 2354 pw.print(mProcessCpuTracker.printCurrentLoad()); 2355 pw.print(mProcessCpuTracker.printCurrentState( 2356 SystemClock.uptimeMillis())); 2357 } 2358 } 2359 }; 2360 2361 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)2362 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2363 PriorityDump.dump(mPriorityDumper, fd, pw, args); 2364 } 2365 } 2366 setCpuInfoService()2367 void setCpuInfoService() { 2368 if (MONITOR_CPU_USAGE) { 2369 ServiceManager.addService("cpuinfo", new CpuBinder(), 2370 /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL); 2371 } 2372 } 2373 AppProfiler(ActivityManagerService service, Looper bgLooper, LowMemDetector detector)2374 AppProfiler(ActivityManagerService service, Looper bgLooper, LowMemDetector detector) { 2375 mService = service; 2376 mProcLock = service.mProcLock; 2377 mBgHandler = new BgHandler(bgLooper); 2378 mLowMemDetector = detector; 2379 mProcessCpuThread = new ProcessCpuThread("CpuTracker"); 2380 } 2381 retrieveSettings()2382 void retrieveSettings() { 2383 final long pssDeferralMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, 2384 ACTIVITY_START_PSS_DEFER_CONFIG, 0L); 2385 DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, 2386 ActivityThread.currentApplication().getMainExecutor(), 2387 mPssDelayConfigListener); 2388 mPssDeferralTime = pssDeferralMs; 2389 } 2390 onActivityManagerInternalAdded()2391 void onActivityManagerInternalAdded() { 2392 mProcessCpuThread.start(); 2393 // Wait for the synchronized block started in mProcessCpuThread, 2394 // so that any other access to mProcessCpuTracker from main thread 2395 // will be blocked during mProcessCpuTracker initialization. 2396 try { 2397 mProcessCpuInitLatch.await(); 2398 } catch (InterruptedException e) { 2399 Slog.wtf(TAG, "Interrupted wait during start", e); 2400 Thread.currentThread().interrupt(); 2401 throw new IllegalStateException("Interrupted wait during start"); 2402 } 2403 } 2404 onActivityLaunched()2405 void onActivityLaunched() { 2406 // This is safe to force to the head of the queue because it relies only 2407 // on refcounting to track begin/end of deferrals, not on actual 2408 // message ordering. We don't care *what* activity is being 2409 // launched; only that we're doing so. 2410 if (mPssDeferralTime > 0) { 2411 final Message msg = mBgHandler.obtainMessage(BgHandler.DEFER_PSS_MSG); 2412 mBgHandler.sendMessageAtFrontOfQueue(msg); 2413 } 2414 } 2415 2416 @GuardedBy("mService") setupProfilerInfoLocked(@onNull IApplicationThread thread, ProcessRecord app, ActiveInstrumentation instr)2417 ProfilerInfo setupProfilerInfoLocked(@NonNull IApplicationThread thread, ProcessRecord app, 2418 ActiveInstrumentation instr) throws IOException, RemoteException { 2419 ProfilerInfo profilerInfo = null; 2420 String preBindAgent = null; 2421 final String processName = app.processName; 2422 synchronized (mProfilerLock) { 2423 if (mProfileData.getProfileApp() != null 2424 && mProfileData.getProfileApp().equals(processName)) { 2425 mProfileData.setProfileProc(app); 2426 if (mProfileData.getProfilerInfo() != null) { 2427 // Send a profiler info object to the app if either a file is given, or 2428 // an agent should be loaded at bind-time. 2429 boolean needsInfo = mProfileData.getProfilerInfo().profileFile != null 2430 || mProfileData.getProfilerInfo().attachAgentDuringBind; 2431 profilerInfo = needsInfo 2432 ? new ProfilerInfo(mProfileData.getProfilerInfo()) : null; 2433 if (mProfileData.getProfilerInfo().agent != null) { 2434 preBindAgent = mProfileData.getProfilerInfo().agent; 2435 } 2436 } 2437 } else if (instr != null && instr.mProfileFile != null) { 2438 profilerInfo = new ProfilerInfo(instr.mProfileFile, null, 0, false, false, null, 2439 false, 0, ProfilerInfo.OUTPUT_VERSION_DEFAULT); 2440 } 2441 if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) { 2442 // We need to do a debuggable check here. See setAgentApp for why the check is 2443 // postponed to here. 2444 if (app.isDebuggable()) { 2445 String agent = mAppAgentMap.get(processName); 2446 // Do not overwrite already requested agent. 2447 if (profilerInfo == null) { 2448 profilerInfo = new ProfilerInfo(null, null, 0, false, false, 2449 mAppAgentMap.get(processName), true, 0, 2450 ProfilerInfo.OUTPUT_VERSION_DEFAULT); 2451 } else if (profilerInfo.agent == null) { 2452 profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true); 2453 } 2454 } 2455 } 2456 2457 if (profilerInfo != null && profilerInfo.profileFd != null) { 2458 profilerInfo.profileFd = profilerInfo.profileFd.dup(); 2459 if (TextUtils.equals(mProfileData.getProfileApp(), processName) 2460 && mProfileData.getProfilerInfo() != null) { 2461 clearProfilerLPf(); 2462 } 2463 } 2464 } 2465 2466 // Check if this is a secondary process that should be incorporated into some 2467 // currently active instrumentation. (Note we do this AFTER all of the profiling 2468 // stuff above because profiling can currently happen only in the primary 2469 // instrumentation process.) 2470 if (mService.mActiveInstrumentation.size() > 0 && instr == null) { 2471 for (int i = mService.mActiveInstrumentation.size() - 1; 2472 i >= 0 && app.getActiveInstrumentation() == null; i--) { 2473 ActiveInstrumentation aInstr = mService.mActiveInstrumentation.get(i); 2474 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) { 2475 synchronized (mProcLock) { 2476 if (aInstr.mTargetProcesses.length == 0) { 2477 // This is the wildcard mode, where every process brought up for 2478 // the target instrumentation should be included. 2479 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) { 2480 mService.mProcessStateController.setActiveInstrumentation(app, 2481 aInstr); 2482 aInstr.mRunningProcesses.add(app); 2483 } 2484 } else { 2485 for (String proc : aInstr.mTargetProcesses) { 2486 if (proc.equals(app.processName)) { 2487 mService.mProcessStateController.setActiveInstrumentation(app, 2488 aInstr); 2489 aInstr.mRunningProcesses.add(app); 2490 break; 2491 } 2492 } 2493 } 2494 } 2495 } 2496 } 2497 } 2498 2499 // If we were asked to attach an agent on startup, do so now, before we're binding 2500 // application code. 2501 if (preBindAgent != null) { 2502 thread.attachAgent(preBindAgent); 2503 } 2504 if (app.isDebuggable()) { 2505 thread.attachStartupAgents(app.info.dataDir); 2506 } 2507 return profilerInfo; 2508 } 2509 2510 @GuardedBy("mService") onCleanupApplicationRecordLocked(ProcessRecord app)2511 void onCleanupApplicationRecordLocked(ProcessRecord app) { 2512 synchronized (mProfilerLock) { 2513 final ProcessProfileRecord profile = app.mProfile; 2514 mProcessesToGc.remove(app); 2515 mPendingPssOrRssProfiles.remove(profile); 2516 profile.abortNextPssTime(); 2517 } 2518 } 2519 2520 @GuardedBy("mService") onAppDiedLocked(ProcessRecord app)2521 void onAppDiedLocked(ProcessRecord app) { 2522 synchronized (mProfilerLock) { 2523 if (mProfileData.getProfileProc() == app) { 2524 clearProfilerLPf(); 2525 } 2526 } 2527 } 2528 2529 @GuardedBy("mProfilerLock") dumpMemWatchProcessesLPf(PrintWriter pw, boolean needSep)2530 boolean dumpMemWatchProcessesLPf(PrintWriter pw, boolean needSep) { 2531 if (mMemWatchProcesses.getMap().size() > 0) { 2532 pw.println(" Mem watch processes:"); 2533 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs = 2534 mMemWatchProcesses.getMap(); 2535 for (int i = procs.size() - 1; i >= 0; i--) { 2536 final String proc = procs.keyAt(i); 2537 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i); 2538 for (int j = uids.size() - 1; j >= 0; j--) { 2539 if (needSep) { 2540 pw.println(); 2541 needSep = false; 2542 } 2543 StringBuilder sb = new StringBuilder(); 2544 sb.append(" ").append(proc).append('/'); 2545 UserHandle.formatUid(sb, uids.keyAt(j)); 2546 Pair<Long, String> val = uids.valueAt(j); 2547 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb); 2548 if (val.second != null) { 2549 sb.append(", report to ").append(val.second); 2550 } 2551 pw.println(sb.toString()); 2552 } 2553 } 2554 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName); 2555 pw.print(" mMemWatchDumpUri="); pw.println(mMemWatchDumpUri); 2556 pw.print(" mMemWatchDumpPid="); pw.println(mMemWatchDumpPid); 2557 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid); 2558 pw.print(" mMemWatchIsUserInitiated="); pw.println(mMemWatchIsUserInitiated); 2559 } 2560 return needSep; 2561 } 2562 2563 @GuardedBy("mService") dumpProfileDataLocked(PrintWriter pw, String dumpPackage, boolean needSep)2564 boolean dumpProfileDataLocked(PrintWriter pw, String dumpPackage, boolean needSep) { 2565 if (mProfileData.getProfileApp() != null || mProfileData.getProfileProc() != null 2566 || (mProfileData.getProfilerInfo() != null 2567 && (mProfileData.getProfilerInfo().profileFile != null 2568 || mProfileData.getProfilerInfo().profileFd != null))) { 2569 if (dumpPackage == null || dumpPackage.equals(mProfileData.getProfileApp())) { 2570 if (needSep) { 2571 pw.println(); 2572 needSep = false; 2573 } 2574 pw.println(" mProfileApp=" + mProfileData.getProfileApp() 2575 + " mProfileProc=" + mProfileData.getProfileProc()); 2576 if (mProfileData.getProfilerInfo() != null) { 2577 pw.println(" mProfileFile=" + mProfileData.getProfilerInfo().profileFile 2578 + " mProfileFd=" + mProfileData.getProfilerInfo().profileFd); 2579 pw.println( 2580 " mSamplingInterval=" + mProfileData.getProfilerInfo().samplingInterval 2581 + " mAutoStopProfiler=" 2582 + mProfileData.getProfilerInfo().autoStopProfiler 2583 + " mStreamingOutput=" 2584 + mProfileData.getProfilerInfo().streamingOutput 2585 + " mClockType=" 2586 + mProfileData.getProfilerInfo().clockType 2587 + " mProfilerOutputVersion=" 2588 + mProfileData.getProfilerInfo().profilerOutputVersion); 2589 pw.println(" mProfileType=" + mProfileType); 2590 } 2591 } 2592 } 2593 return needSep; 2594 } 2595 2596 @GuardedBy("mService") dumpLastMemoryLevelLocked(PrintWriter pw)2597 void dumpLastMemoryLevelLocked(PrintWriter pw) { 2598 switch (mLastMemoryLevel) { 2599 case ADJ_MEM_FACTOR_NORMAL: 2600 pw.println("normal)"); 2601 break; 2602 case ADJ_MEM_FACTOR_MODERATE: 2603 pw.println("moderate)"); 2604 break; 2605 case ADJ_MEM_FACTOR_LOW: 2606 pw.println("low)"); 2607 break; 2608 case ADJ_MEM_FACTOR_CRITICAL: 2609 pw.println("critical)"); 2610 break; 2611 default: 2612 pw.print(mLastMemoryLevel); 2613 pw.println(")"); 2614 break; 2615 } 2616 } 2617 2618 @GuardedBy("mService") dumpMemoryLevelsLocked(PrintWriter pw)2619 void dumpMemoryLevelsLocked(PrintWriter pw) { 2620 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 2621 + " mLastMemoryLevel=" + mLastMemoryLevel 2622 + " mLastNumProcesses=" + mLastNumProcesses); 2623 } 2624 2625 @GuardedBy("mProfilerLock") writeMemWatchProcessToProtoLPf(ProtoOutputStream proto)2626 void writeMemWatchProcessToProtoLPf(ProtoOutputStream proto) { 2627 if (mMemWatchProcesses.getMap().size() > 0) { 2628 final long token = proto.start( 2629 ActivityManagerServiceDumpProcessesProto.MEM_WATCH_PROCESSES); 2630 ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap(); 2631 for (int i = 0; i < procs.size(); i++) { 2632 final String proc = procs.keyAt(i); 2633 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i); 2634 final long ptoken = proto.start( 2635 ActivityManagerServiceDumpProcessesProto.MemWatchProcess.PROCS); 2636 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Process.NAME, 2637 proc); 2638 for (int j = uids.size() - 1; j >= 0; j--) { 2639 final long utoken = proto.start(ActivityManagerServiceDumpProcessesProto 2640 .MemWatchProcess.Process.MEM_STATS); 2641 Pair<Long, String> val = uids.valueAt(j); 2642 proto.write(ActivityManagerServiceDumpProcessesProto 2643 .MemWatchProcess.Process.MemStats.UID, uids.keyAt(j)); 2644 proto.write(ActivityManagerServiceDumpProcessesProto 2645 .MemWatchProcess.Process.MemStats.SIZE, 2646 DebugUtils.sizeValueToString(val.first, new StringBuilder())); 2647 proto.write(ActivityManagerServiceDumpProcessesProto 2648 .MemWatchProcess.Process.MemStats.REPORT_TO, val.second); 2649 proto.end(utoken); 2650 } 2651 proto.end(ptoken); 2652 } 2653 2654 final long dtoken = proto.start( 2655 ActivityManagerServiceDumpProcessesProto.MemWatchProcess.DUMP); 2656 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME, 2657 mMemWatchDumpProcName); 2658 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.URI, 2659 mMemWatchDumpUri.toString()); 2660 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, 2661 mMemWatchDumpPid); 2662 proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, 2663 mMemWatchDumpUid); 2664 proto.write( 2665 ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.IS_USER_INITIATED, 2666 mMemWatchIsUserInitiated); 2667 proto.end(dtoken); 2668 2669 proto.end(token); 2670 } 2671 } 2672 2673 @GuardedBy("mService") writeProfileDataToProtoLocked(ProtoOutputStream proto, String dumpPackage)2674 void writeProfileDataToProtoLocked(ProtoOutputStream proto, String dumpPackage) { 2675 if (mProfileData.getProfileApp() != null || mProfileData.getProfileProc() != null 2676 || (mProfileData.getProfilerInfo() != null 2677 && (mProfileData.getProfilerInfo().profileFile != null 2678 || mProfileData.getProfilerInfo().profileFd != null))) { 2679 if (dumpPackage == null || dumpPackage.equals(mProfileData.getProfileApp())) { 2680 final long token = proto.start(ActivityManagerServiceDumpProcessesProto.PROFILE); 2681 proto.write(ActivityManagerServiceDumpProcessesProto.Profile.APP_NAME, 2682 mProfileData.getProfileApp()); 2683 mProfileData.getProfileProc().dumpDebug(proto, 2684 ActivityManagerServiceDumpProcessesProto.Profile.PROC); 2685 if (mProfileData.getProfilerInfo() != null) { 2686 mProfileData.getProfilerInfo().dumpDebug(proto, 2687 ActivityManagerServiceDumpProcessesProto.Profile.INFO); 2688 proto.write(ActivityManagerServiceDumpProcessesProto.Profile.TYPE, 2689 mProfileType); 2690 } 2691 proto.end(token); 2692 } 2693 } 2694 } 2695 2696 @GuardedBy("mService") writeMemoryLevelsToProtoLocked(ProtoOutputStream proto)2697 void writeMemoryLevelsToProtoLocked(ProtoOutputStream proto) { 2698 proto.write(ActivityManagerServiceDumpProcessesProto.ALLOW_LOWER_MEM_LEVEL, 2699 mAllowLowerMemLevel); 2700 proto.write(ActivityManagerServiceDumpProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel); 2701 proto.write(ActivityManagerServiceDumpProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses); 2702 } 2703 printCurrentCpuState(StringBuilder report, long time)2704 void printCurrentCpuState(StringBuilder report, long time) { 2705 synchronized (mProcessCpuTracker) { 2706 // Only print the first 10 processes 2707 report.append(mProcessCpuTracker.printCurrentState(time, /* maxProcesses= */10)); 2708 } 2709 } 2710 getAppProfileStatsForDebugging(long time, int linesOfStats)2711 Pair<String, String> getAppProfileStatsForDebugging(long time, int linesOfStats) { 2712 String cpuLoad = null; 2713 String stats = null; 2714 synchronized (mProcessCpuTracker) { 2715 updateCpuStatsNow(); 2716 cpuLoad = mProcessCpuTracker.printCurrentLoad(); 2717 stats = mProcessCpuTracker.printCurrentState(time); 2718 } 2719 // Only return linesOfStats lines of Cpu stats. 2720 int toIndex = 0; 2721 for (int i = 0; i <= linesOfStats; i++) { 2722 int nextIndex = stats.indexOf('\n', toIndex); 2723 if (nextIndex == -1) { 2724 toIndex = stats.length(); 2725 break; 2726 } 2727 toIndex = nextIndex + 1; 2728 } 2729 return new Pair(cpuLoad, stats.substring(0, toIndex)); 2730 } 2731 2732 @GuardedBy("mProfilerLock") writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage)2733 void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) { 2734 if (mProcessesToGc.size() > 0) { 2735 long now = SystemClock.uptimeMillis(); 2736 for (int i = 0, size = mProcessesToGc.size(); i < size; i++) { 2737 ProcessRecord r = mProcessesToGc.get(i); 2738 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 2739 continue; 2740 } 2741 final long token = proto.start(fieldId); 2742 final ProcessProfileRecord profile = r.mProfile; 2743 r.dumpDebug(proto, ProcessToGcProto.PROC); 2744 proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, profile.getReportLowMemory()); 2745 proto.write(ProcessToGcProto.NOW_UPTIME_MS, now); 2746 proto.write(ProcessToGcProto.LAST_GCED_MS, profile.getLastRequestedGc()); 2747 proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, profile.getLastLowMemory()); 2748 proto.end(token); 2749 } 2750 } 2751 } 2752 2753 @GuardedBy("mProfilerLock") dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage)2754 boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) { 2755 if (mProcessesToGc.size() > 0) { 2756 boolean printed = false; 2757 long now = SystemClock.uptimeMillis(); 2758 for (int i = 0, size = mProcessesToGc.size(); i < size; i++) { 2759 ProcessRecord proc = mProcessesToGc.get(i); 2760 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 2761 continue; 2762 } 2763 if (!printed) { 2764 if (needSep) pw.println(); 2765 needSep = true; 2766 pw.println(" Processes that are waiting to GC:"); 2767 printed = true; 2768 } 2769 pw.print(" Process "); pw.println(proc); 2770 final ProcessProfileRecord profile = proc.mProfile; 2771 pw.print(" lowMem="); pw.print(profile.getReportLowMemory()); 2772 pw.print(", last gced="); 2773 pw.print(now - profile.getLastRequestedGc()); 2774 pw.print(" ms ago, last lowMem="); 2775 pw.print(now - profile.getLastLowMemory()); 2776 pw.println(" ms ago"); 2777 2778 } 2779 } 2780 return needSep; 2781 } 2782 } 2783