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.app.ActivityManager.processStateAmToProto; 21 22 import android.app.IApplicationThread; 23 import android.content.pm.ApplicationInfo; 24 import android.os.Debug; 25 import android.os.SystemClock; 26 import android.util.DebugUtils; 27 import android.util.TimeUtils; 28 29 import com.android.internal.annotations.CompositeRWLock; 30 import com.android.internal.annotations.GuardedBy; 31 import com.android.internal.app.procstats.ProcessState; 32 import com.android.internal.app.procstats.ProcessStats; 33 import com.android.internal.os.BatteryStatsImpl; 34 import com.android.internal.util.FrameworkStatsLog; 35 import com.android.server.am.ProcessList.ProcStateMemTracker; 36 37 import java.io.PrintWriter; 38 import java.util.concurrent.atomic.AtomicLong; 39 40 /** 41 * Profiling info of the process, such as PSS, cpu, etc. 42 */ 43 final class ProcessProfileRecord { 44 final ProcessRecord mApp; 45 46 private final ActivityManagerService mService; 47 48 final Object mProfilerLock; 49 50 @GuardedBy("mProfilerLock") 51 private final ProcessList.ProcStateMemTracker mProcStateMemTracker = 52 new ProcessList.ProcStateMemTracker(); 53 54 /** 55 * Stats of pss, cpu, etc. 56 */ 57 @GuardedBy("mService.mProcessStats.mLock") 58 private ProcessState mBaseProcessTracker; 59 60 /** 61 * Last time we retrieved PSS data. 62 */ 63 @GuardedBy("mProfilerLock") 64 private long mLastPssTime; 65 66 /** 67 * Next time we want to request PSS data. 68 */ 69 @GuardedBy("mProfilerLock") 70 private long mNextPssTime; 71 72 /** 73 * Initial memory pss of process for idle maintenance. 74 */ 75 @GuardedBy("mProfilerLock") 76 private long mInitialIdlePss; 77 78 /** 79 * Last computed memory pss. 80 */ 81 @GuardedBy("mProfilerLock") 82 private long mLastPss; 83 84 /** 85 * Last computed SwapPss. 86 */ 87 @GuardedBy("mProfilerLock") 88 private long mLastSwapPss; 89 90 /** 91 * Last computed pss when in cached state. 92 */ 93 @GuardedBy("mProfilerLock") 94 private long mLastCachedPss; 95 96 /** 97 * Last computed SwapPss when in cached state. 98 */ 99 @GuardedBy("mProfilerLock") 100 private long mLastCachedSwapPss; 101 102 /** 103 * Last computed memory rss. 104 */ 105 @GuardedBy("mProfilerLock") 106 private long mLastRss; 107 108 /** 109 * Cache of last retrieve memory info, to throttle how frequently apps can request it. 110 */ 111 @GuardedBy("mProfilerLock") 112 private Debug.MemoryInfo mLastMemInfo; 113 114 /** 115 * Cache of last retrieve memory uptime, to throttle how frequently apps can request it. 116 */ 117 @GuardedBy("mProfilerLock") 118 private long mLastMemInfoTime; 119 120 /** 121 * Currently requesting pss for. 122 */ 123 @GuardedBy("mProfilerLock") 124 private int mPssProcState = PROCESS_STATE_NONEXISTENT; 125 126 /** 127 * The type of stat collection that we are currently requesting. 128 */ 129 @GuardedBy("mProfilerLock") 130 private int mPssStatType; 131 132 /** 133 * How long proc has run CPU at last check. 134 */ 135 final AtomicLong mLastCpuTime = new AtomicLong(0); 136 137 /** 138 * How long proc has run CPU most recently. 139 */ 140 final AtomicLong mCurCpuTime = new AtomicLong(0); 141 142 /** 143 * Last selected memory trimming level. 144 */ 145 @CompositeRWLock({"mService", "mProcLock"}) 146 private int mTrimMemoryLevel; 147 148 /** 149 * Want to clean up resources from showing UI? 150 */ 151 @GuardedBy("mProcLock") 152 private boolean mPendingUiClean; 153 154 /** 155 * Pointer to the battery stats of this process. 156 */ 157 private BatteryStatsImpl.Uid.Proc mCurProcBatteryStats; 158 159 /** 160 * When we last asked the app to do a gc. 161 */ 162 @GuardedBy("mProfilerLock") 163 private long mLastRequestedGc; 164 165 /** 166 * When we last told the app that memory is low. 167 */ 168 @CompositeRWLock({"mService", "mProfilerLock"}) 169 private long mLastLowMemory; 170 171 /** 172 * Set to true when waiting to report low mem. 173 */ 174 @GuardedBy("mProfilerLock") 175 private boolean mReportLowMemory; 176 177 // ======================================================================== 178 // Local copies of some process info, to avoid holding global AMS lock 179 @GuardedBy("mProfilerLock") 180 private int mPid; 181 182 @GuardedBy("mProfilerLock") 183 private IApplicationThread mThread; 184 185 @GuardedBy("mProfilerLock") 186 private int mSetProcState; 187 188 @GuardedBy("mProfilerLock") 189 private int mSetAdj; 190 191 @GuardedBy("mProfilerLock") 192 private int mCurRawAdj; 193 194 @GuardedBy("mProfilerLock") 195 private long mLastStateTime; 196 197 private final ActivityManagerGlobalLock mProcLock; 198 ProcessProfileRecord(final ProcessRecord app)199 ProcessProfileRecord(final ProcessRecord app) { 200 mApp = app; 201 mService = app.mService; 202 mProcLock = mService.mProcLock; 203 mProfilerLock = mService.mAppProfiler.mProfilerLock; 204 } 205 init(long now)206 void init(long now) { 207 mLastPssTime = mNextPssTime = now; 208 } 209 210 @GuardedBy("mService.mProcessStats.mLock") getBaseProcessTracker()211 ProcessState getBaseProcessTracker() { 212 return mBaseProcessTracker; 213 } 214 215 @GuardedBy("mService.mProcessStats.mLock") setBaseProcessTracker(ProcessState baseProcessTracker)216 void setBaseProcessTracker(ProcessState baseProcessTracker) { 217 mBaseProcessTracker = baseProcessTracker; 218 } 219 onProcessActive(IApplicationThread thread, ProcessStatsService tracker)220 void onProcessActive(IApplicationThread thread, ProcessStatsService tracker) { 221 if (mThread == null) { 222 synchronized (mProfilerLock) { 223 synchronized (tracker.mLock) { 224 final ProcessState origBase = getBaseProcessTracker(); 225 final PackageList pkgList = mApp.getPkgList(); 226 if (origBase != null) { 227 synchronized (pkgList) { 228 origBase.setState(ProcessStats.STATE_NOTHING, 229 tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), 230 pkgList.getPackageListLocked()); 231 pkgList.forEachPackage((pkgName, holder) -> 232 FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED, 233 mApp.uid, mApp.processName, pkgName, 234 processStateAmToProto(ProcessStats.STATE_NOTHING), 235 holder.appVersion) 236 ); 237 } 238 origBase.makeInactive(); 239 } 240 final ApplicationInfo info = mApp.info; 241 final ProcessState baseProcessTracker = tracker.getProcessStateLocked( 242 info.packageName, info.uid, info.longVersionCode, mApp.processName); 243 setBaseProcessTracker(baseProcessTracker); 244 baseProcessTracker.makeActive(); 245 pkgList.forEachPackage((pkgName, holder) -> { 246 if (holder.state != null && holder.state != origBase) { 247 holder.state.makeInactive(); 248 } 249 tracker.updateProcessStateHolderLocked(holder, pkgName, mApp.info.uid, 250 mApp.info.longVersionCode, mApp.processName); 251 if (holder.state != baseProcessTracker) { 252 holder.state.makeActive(); 253 } 254 }); 255 mThread = thread; 256 } 257 } 258 } else { 259 synchronized (mProfilerLock) { 260 mThread = thread; 261 } 262 } 263 } 264 onProcessInactive(ProcessStatsService tracker)265 void onProcessInactive(ProcessStatsService tracker) { 266 synchronized (mProfilerLock) { 267 synchronized (tracker.mLock) { 268 final ProcessState origBase = getBaseProcessTracker(); 269 if (origBase != null) { 270 final PackageList pkgList = mApp.getPkgList(); 271 synchronized (pkgList) { 272 origBase.setState(ProcessStats.STATE_NOTHING, 273 tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), 274 pkgList.getPackageListLocked()); 275 pkgList.forEachPackage((pkgName, holder) -> 276 FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED, 277 mApp.uid, mApp.processName, pkgName, 278 processStateAmToProto(ProcessStats.STATE_NOTHING), 279 holder.appVersion) 280 ); 281 } 282 origBase.makeInactive(); 283 setBaseProcessTracker(null); 284 pkgList.forEachPackageProcessStats(holder -> { 285 if (holder.state != null && holder.state != origBase) { 286 holder.state.makeInactive(); 287 } 288 holder.pkg = null; 289 holder.state = null; 290 }); 291 } 292 mThread = null; 293 } 294 } 295 } 296 297 @GuardedBy("mProfilerLock") getLastPssTime()298 long getLastPssTime() { 299 return mLastPssTime; 300 } 301 302 @GuardedBy("mProfilerLock") setLastPssTime(long lastPssTime)303 void setLastPssTime(long lastPssTime) { 304 mLastPssTime = lastPssTime; 305 } 306 307 @GuardedBy("mProfilerLock") getNextPssTime()308 long getNextPssTime() { 309 return mNextPssTime; 310 } 311 312 @GuardedBy("mProfilerLock") setNextPssTime(long nextPssTime)313 void setNextPssTime(long nextPssTime) { 314 mNextPssTime = nextPssTime; 315 } 316 317 @GuardedBy("mProfilerLock") getInitialIdlePss()318 long getInitialIdlePss() { 319 return mInitialIdlePss; 320 } 321 322 @GuardedBy("mProfilerLock") setInitialIdlePss(long initialIdlePss)323 void setInitialIdlePss(long initialIdlePss) { 324 mInitialIdlePss = initialIdlePss; 325 } 326 327 @GuardedBy("mProfilerLock") getLastPss()328 long getLastPss() { 329 return mLastPss; 330 } 331 332 @GuardedBy("mProfilerLock") setLastPss(long lastPss)333 void setLastPss(long lastPss) { 334 mLastPss = lastPss; 335 } 336 337 @GuardedBy("mProfilerLock") getLastCachedPss()338 long getLastCachedPss() { 339 return mLastCachedPss; 340 } 341 342 @GuardedBy("mProfilerLock") setLastCachedPss(long lastCachedPss)343 void setLastCachedPss(long lastCachedPss) { 344 mLastCachedPss = lastCachedPss; 345 } 346 347 @GuardedBy("mProfilerLock") getLastSwapPss()348 long getLastSwapPss() { 349 return mLastSwapPss; 350 } 351 352 @GuardedBy("mProfilerLock") setLastSwapPss(long lastSwapPss)353 void setLastSwapPss(long lastSwapPss) { 354 mLastSwapPss = lastSwapPss; 355 } 356 357 @GuardedBy("mProfilerLock") getLastCachedSwapPss()358 long getLastCachedSwapPss() { 359 return mLastCachedSwapPss; 360 } 361 362 @GuardedBy("mProfilerLock") setLastCachedSwapPss(long lastCachedSwapPss)363 void setLastCachedSwapPss(long lastCachedSwapPss) { 364 mLastCachedSwapPss = lastCachedSwapPss; 365 } 366 367 @GuardedBy("mProfilerLock") getLastRss()368 long getLastRss() { 369 return mLastRss; 370 } 371 372 @GuardedBy("mProfilerLock") setLastRss(long lastRss)373 void setLastRss(long lastRss) { 374 mLastRss = lastRss; 375 } 376 377 @GuardedBy("mProfilerLock") getLastMemInfo()378 Debug.MemoryInfo getLastMemInfo() { 379 return mLastMemInfo; 380 } 381 382 @GuardedBy("mProfilerLock") setLastMemInfo(Debug.MemoryInfo lastMemInfo)383 void setLastMemInfo(Debug.MemoryInfo lastMemInfo) { 384 mLastMemInfo = lastMemInfo; 385 } 386 387 @GuardedBy("mProfilerLock") getLastMemInfoTime()388 long getLastMemInfoTime() { 389 return mLastMemInfoTime; 390 } 391 392 @GuardedBy("mProfilerLock") setLastMemInfoTime(long lastMemInfoTime)393 void setLastMemInfoTime(long lastMemInfoTime) { 394 mLastMemInfoTime = lastMemInfoTime; 395 } 396 397 @GuardedBy("mProfilerLock") getPssProcState()398 int getPssProcState() { 399 return mPssProcState; 400 } 401 402 @GuardedBy("mProfilerLock") setPssProcState(int pssProcState)403 void setPssProcState(int pssProcState) { 404 mPssProcState = pssProcState; 405 } 406 407 @GuardedBy("mProfilerLock") getPssStatType()408 int getPssStatType() { 409 return mPssStatType; 410 } 411 412 @GuardedBy("mProfilerLock") setPssStatType(int pssStatType)413 void setPssStatType(int pssStatType) { 414 mPssStatType = pssStatType; 415 } 416 417 @GuardedBy(anyOf = {"mService", "mProcLock"}) getTrimMemoryLevel()418 int getTrimMemoryLevel() { 419 return mTrimMemoryLevel; 420 } 421 422 @GuardedBy({"mService", "mProcLock"}) setTrimMemoryLevel(int trimMemoryLevel)423 void setTrimMemoryLevel(int trimMemoryLevel) { 424 mTrimMemoryLevel = trimMemoryLevel; 425 } 426 427 @GuardedBy("mProcLock") hasPendingUiClean()428 boolean hasPendingUiClean() { 429 return mPendingUiClean; 430 } 431 432 @GuardedBy("mProcLock") setPendingUiClean(boolean pendingUiClean)433 void setPendingUiClean(boolean pendingUiClean) { 434 mPendingUiClean = pendingUiClean; 435 mApp.getWindowProcessController().setPendingUiClean(pendingUiClean); 436 } 437 getCurProcBatteryStats()438 BatteryStatsImpl.Uid.Proc getCurProcBatteryStats() { 439 return mCurProcBatteryStats; 440 } 441 setCurProcBatteryStats(BatteryStatsImpl.Uid.Proc curProcBatteryStats)442 void setCurProcBatteryStats(BatteryStatsImpl.Uid.Proc curProcBatteryStats) { 443 mCurProcBatteryStats = curProcBatteryStats; 444 } 445 446 @GuardedBy("mProfilerLock") getLastRequestedGc()447 long getLastRequestedGc() { 448 return mLastRequestedGc; 449 } 450 451 @GuardedBy("mProfilerLock") setLastRequestedGc(long lastRequestedGc)452 void setLastRequestedGc(long lastRequestedGc) { 453 mLastRequestedGc = lastRequestedGc; 454 } 455 456 @GuardedBy(anyOf = {"mService", "mProfilerLock"}) getLastLowMemory()457 long getLastLowMemory() { 458 return mLastLowMemory; 459 } 460 461 @GuardedBy({"mService", "mProfilerLock"}) setLastLowMemory(long lastLowMemory)462 void setLastLowMemory(long lastLowMemory) { 463 mLastLowMemory = lastLowMemory; 464 } 465 466 @GuardedBy("mProfilerLock") getReportLowMemory()467 boolean getReportLowMemory() { 468 return mReportLowMemory; 469 } 470 471 @GuardedBy("mProfilerLock") setReportLowMemory(boolean reportLowMemory)472 void setReportLowMemory(boolean reportLowMemory) { 473 mReportLowMemory = reportLowMemory; 474 } 475 addPss(long pss, long uss, long rss, boolean always, int type, long duration)476 void addPss(long pss, long uss, long rss, boolean always, int type, long duration) { 477 synchronized (mService.mProcessStats.mLock) { 478 final ProcessState tracker = mBaseProcessTracker; 479 if (tracker != null) { 480 final PackageList pkgList = mApp.getPkgList(); 481 synchronized (pkgList) { 482 tracker.addPss(pss, uss, rss, always, type, duration, 483 pkgList.getPackageListLocked()); 484 } 485 } 486 } 487 } 488 reportExcessiveCpu()489 void reportExcessiveCpu() { 490 synchronized (mService.mProcessStats.mLock) { 491 final ProcessState tracker = mBaseProcessTracker; 492 if (tracker != null) { 493 final PackageList pkgList = mApp.getPkgList(); 494 synchronized (pkgList) { 495 tracker.reportExcessiveCpu(pkgList.getPackageListLocked()); 496 } 497 } 498 } 499 } 500 reportCachedKill()501 void reportCachedKill() { 502 synchronized (mService.mProcessStats.mLock) { 503 final ProcessState tracker = mBaseProcessTracker; 504 if (tracker != null) { 505 final PackageList pkgList = mApp.getPkgList(); 506 synchronized (pkgList) { 507 tracker.reportCachedKill(pkgList.getPackageListLocked(), mLastCachedPss); 508 pkgList.forEachPackageProcessStats(holder -> 509 FrameworkStatsLog.write(FrameworkStatsLog.CACHED_KILL_REPORTED, 510 mApp.info.uid, 511 holder.state.getName(), 512 holder.state.getPackage(), 513 mLastCachedPss, 514 holder.appVersion) 515 ); 516 } 517 } 518 } 519 } 520 setProcessTrackerState(int procState, int memFactor, long now)521 void setProcessTrackerState(int procState, int memFactor, long now) { 522 synchronized (mService.mProcessStats.mLock) { 523 final ProcessState tracker = mBaseProcessTracker; 524 if (tracker != null) { 525 if (procState != PROCESS_STATE_NONEXISTENT) { 526 final PackageList pkgList = mApp.getPkgList(); 527 synchronized (pkgList) { 528 tracker.setState(procState, memFactor, now, 529 pkgList.getPackageListLocked()); 530 } 531 } 532 } 533 } 534 } 535 536 @GuardedBy("mProfilerLock") commitNextPssTime()537 void commitNextPssTime() { 538 commitNextPssTime(mProcStateMemTracker); 539 } 540 541 @GuardedBy("mProfilerLock") abortNextPssTime()542 void abortNextPssTime() { 543 abortNextPssTime(mProcStateMemTracker); 544 } 545 546 @GuardedBy("mProfilerLock") computeNextPssTime(int procState, boolean test, boolean sleeping, long now)547 long computeNextPssTime(int procState, boolean test, boolean sleeping, long now) { 548 return ProcessList.computeNextPssTime(procState, mProcStateMemTracker, test, sleeping, now); 549 } 550 commitNextPssTime(ProcStateMemTracker tracker)551 private static void commitNextPssTime(ProcStateMemTracker tracker) { 552 if (tracker.mPendingMemState >= 0) { 553 tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState; 554 tracker.mScalingFactor[tracker.mPendingMemState] = tracker.mPendingScalingFactor; 555 tracker.mTotalHighestMem = tracker.mPendingHighestMemState; 556 tracker.mPendingMemState = -1; 557 } 558 } 559 abortNextPssTime(ProcStateMemTracker tracker)560 private static void abortNextPssTime(ProcStateMemTracker tracker) { 561 tracker.mPendingMemState = -1; 562 } 563 564 @GuardedBy("mProfilerLock") getPid()565 int getPid() { 566 return mPid; 567 } 568 569 @GuardedBy("mProfilerLock") setPid(int pid)570 void setPid(int pid) { 571 mPid = pid; 572 } 573 574 @GuardedBy("mProfilerLock") getThread()575 IApplicationThread getThread() { 576 return mThread; 577 } 578 579 @GuardedBy("mProfilerLock") getSetProcState()580 int getSetProcState() { 581 return mSetProcState; 582 } 583 584 @GuardedBy("mProfilerLock") getSetAdj()585 int getSetAdj() { 586 return mSetAdj; 587 } 588 589 @GuardedBy("mProfilerLock") getCurRawAdj()590 int getCurRawAdj() { 591 return mCurRawAdj; 592 } 593 594 @GuardedBy("mProfilerLock") getLastStateTime()595 long getLastStateTime() { 596 return mLastStateTime; 597 } 598 599 @GuardedBy({"mService", "mProfilerLock"}) updateProcState(ProcessStateRecord state)600 void updateProcState(ProcessStateRecord state) { 601 mSetProcState = state.getCurProcState(); 602 mSetAdj = state.getCurAdj(); 603 mCurRawAdj = state.getCurRawAdj(); 604 mLastStateTime = state.getLastStateTime(); 605 } 606 607 @GuardedBy("mService") dumpPss(PrintWriter pw, String prefix, long nowUptime)608 void dumpPss(PrintWriter pw, String prefix, long nowUptime) { 609 synchronized (mProfilerLock) { 610 pw.print(prefix); 611 pw.print("lastPssTime="); 612 TimeUtils.formatDuration(mLastPssTime, nowUptime, pw); 613 pw.print(" pssProcState="); 614 pw.print(mPssProcState); 615 pw.print(" pssStatType="); 616 pw.print(mPssStatType); 617 pw.print(" nextPssTime="); 618 TimeUtils.formatDuration(mNextPssTime, nowUptime, pw); 619 pw.println(); 620 pw.print(prefix); 621 pw.print("lastPss="); 622 DebugUtils.printSizeValue(pw, mLastPss * 1024); 623 pw.print(" lastSwapPss="); 624 DebugUtils.printSizeValue(pw, mLastSwapPss * 1024); 625 pw.print(" lastCachedPss="); 626 DebugUtils.printSizeValue(pw, mLastCachedPss * 1024); 627 pw.print(" lastCachedSwapPss="); 628 DebugUtils.printSizeValue(pw, mLastCachedSwapPss * 1024); 629 pw.print(" lastRss="); 630 DebugUtils.printSizeValue(pw, mLastRss * 1024); 631 pw.println(); 632 pw.print(prefix); 633 pw.print("trimMemoryLevel="); 634 pw.println(mTrimMemoryLevel); 635 pw.print(prefix); pw.print("procStateMemTracker: "); 636 mProcStateMemTracker.dumpLine(pw); 637 pw.print(prefix); 638 pw.print("lastRequestedGc="); 639 TimeUtils.formatDuration(mLastRequestedGc, nowUptime, pw); 640 pw.print(" lastLowMemory="); 641 TimeUtils.formatDuration(mLastLowMemory, nowUptime, pw); 642 pw.print(" reportLowMemory="); 643 pw.println(mReportLowMemory); 644 } 645 } 646 dumpCputime(PrintWriter pw, String prefix)647 void dumpCputime(PrintWriter pw, String prefix) { 648 final long lastCpuTime = mLastCpuTime.get(); 649 pw.print(prefix); 650 pw.print("lastCpuTime="); 651 pw.print(lastCpuTime); 652 if (lastCpuTime > 0) { 653 pw.print(" timeUsed="); 654 TimeUtils.formatDuration(mCurCpuTime.get() - lastCpuTime, pw); 655 } 656 pw.println(); 657 } 658 } 659