長い関数だなー。
Cross Reference: /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
20500 final void updateOomAdjLocked() {
20501 final ActivityRecord TOP_ACT = resumedAppLocked();
20502 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20503 final long now = SystemClock.uptimeMillis();
20504 final long nowElapsed = SystemClock.elapsedRealtime();
20505 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20506 final int N = mLruProcesses.size();
20507
20508 if (false) {
20509 RuntimeException e = new RuntimeException();
20510 e.fillInStackTrace();
20511 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20512 }
20513
20514
20515 for (int i=mActiveUids.size()-1; i>=0; i--) {
20516 final UidRecord uidRec = mActiveUids.valueAt(i);
20517 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20518 "Starting update of " + uidRec);
20519 uidRec.reset();
20520 }
20521
20522 mStackSupervisor.rankTaskLayersIfNeeded();
20523
20524 mAdjSeq++;
20525 mNewNumServiceProcs = 0;
20526 mNewNumAServiceProcs = 0;
20527
20528 final int emptyProcessLimit;
20529 final int cachedProcessLimit;
20530 if (mProcessLimit <= 0) {
20531 emptyProcessLimit = cachedProcessLimit = 0;
20532 } else if (mProcessLimit == 1) {
20533 emptyProcessLimit = 1;
20534 cachedProcessLimit = 0;
20535 } else {
20536 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20537 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20538 }
20539
20540
20541
20542
20543
20544 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20545 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20546 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20547 if (numEmptyProcs > cachedProcessLimit) {
20548
20549
20550
20551
20552
20553
20554 numEmptyProcs = cachedProcessLimit;
20555 }
20556 int emptyFactor = numEmptyProcs/numSlots;
20557 if (emptyFactor < 1) emptyFactor = 1;
20558 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20559 if (cachedFactor < 1) cachedFactor = 1;
20560 int stepCached = 0;
20561 int stepEmpty = 0;
20562 int numCached = 0;
20563 int numEmpty = 0;
20564 int numTrimming = 0;
20565
20566 mNumNonCachedProcs = 0;
20567 mNumCachedHiddenProcs = 0;
20568
20569
20570
20571 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20572 int nextCachedAdj = curCachedAdj+1;
20573 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20574 int nextEmptyAdj = curEmptyAdj+2;
20575 for (int i=N-1; i>=0; i--) {
20576 ProcessRecord app = mLruProcesses.get(i);
20577 if (!app.killedByAm && app.thread != null) {
20578 app.procStateChanged = false;
20579 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20580
20581
20582
20583 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20584 switch (app.curProcState) {
20585 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20586 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20587
20588
20589
20590 app.curRawAdj = curCachedAdj;
20591 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20592 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20593 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20594 + ")");
20595 if (curCachedAdj != nextCachedAdj) {
20596 stepCached++;
20597 if (stepCached >= cachedFactor) {
20598 stepCached = 0;
20599 curCachedAdj = nextCachedAdj;
20600 nextCachedAdj += 2;
20601 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20602 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20603 }
20604 }
20605 }
20606 break;
20607 default:
20608
20609
20610
20611
20612
20613 app.curRawAdj = curEmptyAdj;
20614 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20615 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20616 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20617 + ")");
20618 if (curEmptyAdj != nextEmptyAdj) {
20619 stepEmpty++;
20620 if (stepEmpty >= emptyFactor) {
20621 stepEmpty = 0;
20622 curEmptyAdj = nextEmptyAdj;
20623 nextEmptyAdj += 2;
20624 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20625 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20626 }
20627 }
20628 }
20629 break;
20630 }
20631 }
20632
20633 applyOomAdjLocked(app, true, now, nowElapsed);
20634
20635
20636 switch (app.curProcState) {
20637 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20638 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20639 mNumCachedHiddenProcs++;
20640 numCached++;
20641 if (numCached > cachedProcessLimit) {
20642 app.kill("cached #" + numCached, true);
20643 }
20644 break;
20645 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20646 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20647 && app.lastActivityTime < oldTime) {
20648 app.kill("empty for "
20649 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20650 / 1000) + "s", true);
20651 } else {
20652 numEmpty++;
20653 if (numEmpty > emptyProcessLimit) {
20654 app.kill("empty #" + numEmpty, true);
20655 }
20656 }
20657 break;
20658 default:
20659 mNumNonCachedProcs++;
20660 break;
20661 }
20662
20663 if (app.isolated && app.services.size() <= 0) {
20664
20665
20666
20667
20668
20669
20670 app.kill("isolated not needed", true);
20671 } else {
20672
20673 final UidRecord uidRec = app.uidRecord;
20674 if (uidRec != null && uidRec.curProcState > app.curProcState) {
20675 uidRec.curProcState = app.curProcState;
20676 }
20677 }
20678
20679 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20680 && !app.killedByAm) {
20681 numTrimming++;
20682 }
20683 }
20684 }
20685
20686 mNumServiceProcs = mNewNumServiceProcs;
20687
20688
20689
20690
20691
20692
20693
20694 final int numCachedAndEmpty = numCached + numEmpty;
20695 int memFactor;
20696 if (numCached <= ProcessList.TRIM_CACHED_APPS
20697 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20698 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20699 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20700 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20701 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20702 } else {
20703 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20704 }
20705 } else {
20706 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20707 }
20708
20709
20710
20711 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20712 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20713 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20714 if (memFactor > mLastMemoryLevel) {
20715 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20716 memFactor = mLastMemoryLevel;
20717 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20718 }
20719 }
20720 if (memFactor != mLastMemoryLevel) {
20721 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20722 }
20723 mLastMemoryLevel = memFactor;
20724 mLastNumProcesses = mLruProcesses.size();
20725 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20726 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20727 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20728 if (mLowRamStartTime == 0) {
20729 mLowRamStartTime = now;
20730 }
20731 int step = 0;
20732 int fgTrimLevel;
20733 switch (memFactor) {
20734 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20735 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20736 break;
20737 case ProcessStats.ADJ_MEM_FACTOR_LOW:
20738 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20739 break;
20740 default:
20741 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20742 break;
20743 }
20744 int factor = numTrimming/3;
20745 int minFactor = 2;
20746 if (mHomeProcess != null) minFactor++;
20747 if (mPreviousProcess != null) minFactor++;
20748 if (factor < minFactor) factor = minFactor;
20749 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20750 for (int i=N-1; i>=0; i--) {
20751 ProcessRecord app = mLruProcesses.get(i);
20752 if (allChanged || app.procStateChanged) {
20753 setProcessTrackerStateLocked(app, trackerMemFactor, now);
20754 app.procStateChanged = false;
20755 }
20756 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20757 && !app.killedByAm) {
20758 if (app.trimMemoryLevel < curLevel && app.thread != null) {
20759 try {
20760 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20761 "Trimming memory of " + app.processName + " to " + curLevel);
20762 app.thread.scheduleTrimMemory(curLevel);
20763 } catch (RemoteException e) {
20764 }
20765 if (false) {
20766
20767
20768
20769 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20770 && app != mHomeProcess && app != mPreviousProcess) {
20771
20772
20773
20774
20775 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20776 }
20777 }
20778 }
20779 app.trimMemoryLevel = curLevel;
20780 step++;
20781 if (step >= factor) {
20782 step = 0;
20783 switch (curLevel) {
20784 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20785 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20786 break;
20787 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20788 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20789 break;
20790 }
20791 }
20792 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20793 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20794 && app.thread != null) {
20795 try {
20796 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20797 "Trimming memory of heavy-weight " + app.processName
20798 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20799 app.thread.scheduleTrimMemory(
20800 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20801 } catch (RemoteException e) {
20802 }
20803 }
20804 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20805 } else {
20806 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20807 || app.systemNoUi) && app.pendingUiClean) {
20808
20809
20810
20811 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20812 if (app.trimMemoryLevel < level && app.thread != null) {
20813 try {
20814 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20815 "Trimming memory of bg-ui " + app.processName
20816 + " to " + level);
20817 app.thread.scheduleTrimMemory(level);
20818 } catch (RemoteException e) {
20819 }
20820 }
20821 app.pendingUiClean = false;
20822 }
20823 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20824 try {
20825 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20826 "Trimming memory of fg " + app.processName
20827 + " to " + fgTrimLevel);
20828 app.thread.scheduleTrimMemory(fgTrimLevel);
20829 } catch (RemoteException e) {
20830 }
20831 }
20832 app.trimMemoryLevel = fgTrimLevel;
20833 }
20834 }
20835 } else {
20836 if (mLowRamStartTime != 0) {
20837 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20838 mLowRamStartTime = 0;
20839 }
20840 for (int i=N-1; i>=0; i--) {
20841 ProcessRecord app = mLruProcesses.get(i);
20842 if (allChanged || app.procStateChanged) {
20843 setProcessTrackerStateLocked(app, trackerMemFactor, now);
20844 app.procStateChanged = false;
20845 }
20846 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20847 || app.systemNoUi) && app.pendingUiClean) {
20848 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20849 && app.thread != null) {
20850 try {
20851 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20852 "Trimming memory of ui hidden " + app.processName
20853 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20854 app.thread.scheduleTrimMemory(
20855 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20856 } catch (RemoteException e) {
20857 }
20858 }
20859 app.pendingUiClean = false;
20860 }
20861 app.trimMemoryLevel = 0;
20862 }
20863 }
20864
20865 if (mAlwaysFinishActivities) {
20866
20867
20868 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20869 }
20870
20871 if (allChanged) {
20872 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20873 }
20874
20875
20876 for (int i=mActiveUids.size()-1; i>=0; i--) {
20877 final UidRecord uidRec = mActiveUids.valueAt(i);
20878 int uidChange = UidRecord.CHANGE_PROCSTATE;
20879 if (uidRec.setProcState != uidRec.curProcState) {
20880 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20881 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20882 + " to " + uidRec.curProcState);
20883 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20884 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20885 uidRec.lastBackgroundTime = nowElapsed;
20886 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20887
20888
20889
20890
20891 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20892 }
20893 }
20894 } else {
20895 if (uidRec.idle) {
20896 uidChange = UidRecord.CHANGE_ACTIVE;
20897 uidRec.idle = false;
20898 }
20899 uidRec.lastBackgroundTime = 0;
20900 }
20901 uidRec.setProcState = uidRec.curProcState;
20902 enqueueUidChangeLocked(uidRec, -1, uidChange);
20903 noteUidProcessState(uidRec.uid, uidRec.curProcState);
20904 }
20905 }
20906
20907 if (mProcessStats.shouldWriteNowLocked(now)) {
20908 mHandler.post(new Runnable() {
20909 @Override public void run() {
20910 synchronized (ActivityManagerService.this) {
20911 mProcessStats.writeStateAsyncLocked();
20912 }
20913 }
20914 });
20915 }
20916
20917 if (DEBUG_OOM_ADJ) {
20918 final long duration = SystemClock.uptimeMillis() - now;
20919 if (false) {
20920 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms", <========
20921 new RuntimeException("here").fillInStackTrace());
20922 } else {
20923 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms"); <========
20924 }
20925 }
20926 }