[LMKD] [Android] 进程OomAdj调整分析:OomAdj调整次数(2)

一. 怎么调整进程的OoMAdj的


主要就靠frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java#updateOomAdjLockedProcessRecord进行调整,也只有这一个调整入口,都是从AMS调用updateOomAdjLocked开始调整,如下代码

@GuardedBy("this")
    final void updateOomAdjLocked(String oomAdjReason) {
        mOomAdjuster.updateOomAdjLocked(oomAdjReason);
    }

    /**
     * Update OomAdj for a specific process and its reachable processes.
     *
     * @param app The process to update
     * @param oomAdjReason
     * @return whether updateOomAdjLocked(app) was successful.
     */
    @GuardedBy("this")
    final boolean updateOomAdjLocked(ProcessRecord app, String oomAdjReason) {
        return mOomAdjuster.updateOomAdjLocked(app, oomAdjReason);
    }

二. OomAdj调整次数分析

以下调整都是通过AMS#updateOomAdjLocked进行调整

  • SystemServer启动核心进程时

    frameworks/base/services/java/com/android/server/SystemServer.java

    private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
    				// Set up the Application instance for the system process and get started.
            t.traceBegin("SetSystemProcess");
            mActivityManagerService.**setSystemProcess**();
            t.traceEnd();
    }
    

    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    public void setSystemProcess() {
            try {
    						// AMS中注册各种服务和进程
                ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                        DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
                ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
                ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
                        DUMP_FLAG_PRIORITY_HIGH);
                ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
                ServiceManager.addService("dbinfo", new DbBinder(this));
                mAppProfiler.setCpuInfoService();
                ServiceManager.addService("permission", new PermissionController(this));
                ServiceManager.addService("processinfo", new ProcessInfoService(this));
                ServiceManager.addService("cacheinfo", new CacheBinder(this));
                Log.d(TAG, "leilei [startOtherServices-setSystemProcess] APPLICATION_KEEP_ALIVE");
                mKeepAliveManagerService = new KeepAliveManagerService(mContext,this);
                ServiceManager.addService(Context.APPLICATION_KEEP_ALIVE, mKeepAliveManagerService);
                mKeepAliveManager = (KeepAliveManager) mContext.getSystemService(Context.APPLICATION_KEEP_ALIVE);
    						// 获取“android”应用程序,并安装它
                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                        "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
                mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
    
                synchronized (this) {
    								// 创建系统进程
                    ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
                            false,
                            0,
                            new HostingRecord("system"));
                    app.setPersistent(true);
                    app.setPid(MY_PID);
                    app.mState.setMaxAdj(ProcessList.SYSTEM_ADJ);
    								// 给该进程创建ActivityThread
    								// getApplicationThread获取的是默认就new出来的对象,用于system的ActivityThread
                    app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                    addPidLocked(app);
    								// 更新进程lru使用情况
                    updateLruProcessLocked(app, false, null);
    								// 开始调整进程oomAdj优先级和进程状态
                    **updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);**
                }
            } catch (PackageManager.NameNotFoundException e) {
                throw new RuntimeException(
                        "Unable to find android system package", e);
            }
    					...
        }
    

    以上代码主要创建了”system”进程,并调用updateOomAdjLocked调整进程的oomAdj值和进程状态,这里就是AMS#updateOomAdjLocked,并开始进入OomAdjuster.java中调整进程优先级,具体怎么调整的暂不分析,后面分析,这里只分析入口在哪

  • 应用进程启动时(ActivityThread进程已经fork出来的情况—绑定application)

    应用程序启动流程,后续会通过AMS创建并绑定Application,所以直接看以下代码

    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
                int pid, int callingUid, long startSeq) {
    			...
    			// 应用启动过程中,初始化进程状态
    			synchronized (mProcLock) {
                app.mState.setCurAdj(ProcessList.INVALID_ADJ);
                app.mState.setSetAdj(ProcessList.INVALID_ADJ);
                app.mState.setVerifiedAdj(ProcessList.INVALID_ADJ);
                mOomAdjuster.setAttachingSchedGroupLSP(app);
                app.mState.setForcingToImportant(null);// 这个方法比较常用,有着奇效
                updateProcessForegroundLocked(app, false, 0, false);
                app.mState.setHasShownUi(false);
                app.mState.setCached(false);
                app.setDebugging(false);
                app.setKilledByAm(false);
                app.setKilled(false);
                // We carefully use the same state that PackageManager uses for
                // filtering, since we use this flag to decide if we need to install
                // providers when user is unlocked later
                app.setUnlocked(StorageManager.isUserKeyUnlocked(app.userId));
            }
    				...
    				// 调用indApplication,创建App的Application和activity,这里不详细分析
    				thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
                            null, null, null, testMode,
                            mBinderTransactionTrackingEnabled, enableTrackAllocation,
                            isRestrictedBackupMode || !normalMode, app.isPersistent(),
                            new Configuration(app.getWindowProcessController().getConfiguration()),
                            app.getCompat(), getCommonServicesLocked(app.isolated),
                            mCoreSettingsObserver.getCoreSettingsLocked(),
                            buildSerial, autofillOptions, contentCaptureOptions,
                            app.getDisabledCompatChanges(), serializedSystemFontMap);
    				// 应用程序启动流程,绑定application流程也会调整updateOomAdjLocked,进程adj
            if (!didSomething) {
                updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_PROCESS_BEGIN);
                checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
            }
    				...
    
    }
    

    应用进程fork出来后,会走到AMS进行application绑定流程,此时application还没创建出来,会在这里调整进程状态的初始值和调用updateOomAdjLocked进行进程状态的变更。该方法不做深入分析,后面单独分析

  • Service启动时—依赖应用进程—属于同个进程

    应用程序启动流程,后续会通过AMS创建并绑定Application,绑定时会检查该进程是否具有Service组件,若有则调用realStartServiceLocked去启动服务,并调整进程状态和优先级,所以直接看以下代码

    frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
                int pid, int callingUid, long startSeq) {
    			...
    				// 查找应在此进程中运行的任何服务...
            if (!badApp) {
                try {
                    didSomething |= mServices.**attachApplicationLocked**(app, processName);
                    checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                    badApp = true;
                }
            }
    				...
    

    进入ActiveService#attachApplicationLocked,frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

    boolean attachApplicationLocked(ProcessRecord proc, String processName)
                throws RemoteException {
    				boolean didSomething = false;
            // Collect any services that are waiting for this process to come up.
    				// mPendingServices:待启动的服务
            if (mPendingServices.size() > 0) {
    						// 服务也有一个Record对象
                ServiceRecord sr = null;
                try {
    								// 遍历每个服务,进行启动
                    for (int i=0; i<mPendingServices.size(); i++) {
                        sr = mPendingServices.get(i);
                        ...
                        final IApplicationThread thread = proc.getThread();
                        final int pid = proc.getPid();
                        final UidRecord uidRecord = proc.getUidRecord();
                        mPendingServices.remove(i);
                        i--;
                        proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode,
                                mAm.mProcessStats);
    										// 启动服务,并调整进程优先级
                        **realStartServiceLocked**(sr, proc, thread, pid, uidRecord, sr.createdFromFg,
                                true);
                        didSomething = true;
                        if (!isServiceNeededLocked(sr, false, false)) {
                            // We were waiting for this service to start, but it is actually no
                            // longer needed.  This could happen because bringDownServiceIfNeeded
                            // won't bring down a service that is pending...  so now the pending
                            // is done, so let's drop it.
                            bringDownServiceLocked(sr, true);
                        }
                        /* Will be a no-op if nothing pending */
                        mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
                    }
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception in new application when starting service "
                            + sr.shortInstanceName, e);
                    throw e;
                }
            }
    
    }
    

    继续分析realStartServiceLocked

    private void realStartServiceLocked(ServiceRecord r, ProcessRecord app,
                IApplicationThread thread, int pid, UidRecord uidRecord, boolean execInFg,
                boolean enqueueOomAdj) throws RemoteException {
    				if (thread == null) {
                throw new RemoteException();
            }
            if (DEBUG_MU)
                Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
                        + ", ProcessRecord.uid = " + app.uid);
    				// ServiceRecord和ProcessRecord关联,也就是ServiceRecord所在的进程就是ProcessRecord
            r.setProcess(app, thread, pid, uidRecord);
            r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
    				// 获取该进程所有的服务
            final ProcessServiceRecord psr = app.mServices;
    				// 循环启动ServiceRecord服务
            final boolean newService = psr.startService(r);
            bumpServiceExecutingLocked(r, execInFg, "create", null /* oomAdjReason */);
    				// 更新进程状态的使用情况--Lru规则
            mAm.**updateLruProcessLocked**(app, false, null);
    				// 判断该服务是否是前台服务,赋予前台服务的标志,注意第二个参数false,该方法内虽然也有调整进程优先级和oomadj
    				// 但是这里传递的false,所以不会去调整进程优先级和状态
            **updateServiceForegroundLocked**(psr, /* oomAdj= */ false);
            // Force an immediate oomAdjUpdate, so the client app could be in the correct process state
            // before doing any service related transactions
            mAm.enqueueOomAdjTargetLocked(app);
    				// 调整进程优先级和进程状态,mAm就是AMS
            mAm.**updateOomAdjLocked**(app, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
    
    }
    

    以上就是服务的启动过程,前台服务的处理,然后会继续调用AMS的updateOomAdjLocked去调整进程优先级和状态

  • 进程被Kill时也会调整

    • 例如进程死亡时,在attachApplicationLocked的时候会注册IApplicationThread的Binder死亡回调

      @GuardedBy("this")
          private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
                  int pid, int callingUid, long startSeq) {
      				final String processName = app.processName;
              try {
                  **AppDeathRecipient adr = new AppDeathRecipient(
                          app, pid, thread);**
                  t**hread.asBinder().linkToDeath(adr, 0);**
                  **app.setDeathRecipient(adr);**
              } catch (RemoteException e) {
                  app.resetPackageList(mProcessStats);
                  mProcessList.startProcessLocked(app,
                          new HostingRecord("link fail", processName),
                          ZYGOTE_POLICY_FLAG_EMPTY);
                  return false;
              }
      		}
      
      private final class AppDeathRecipient implements IBinder.DeathRecipient {
              final ProcessRecord mApp;
              final int mPid;
              final IApplicationThread mAppThread;
      
              AppDeathRecipient(ProcessRecord app, int pid,
                      IApplicationThread thread) {
                  if (DEBUG_ALL) Slog.v(
                      TAG, "New death recipient " + this
                       + " for thread " + thread.asBinder());
                  mApp = app;
                  mPid = pid;
                  mAppThread = thread;
              }
      
              @Override
              public void binderDied() {
                  if (DEBUG_ALL) Slog.v(
                      TAG, "Death received in " + this
                      + " for thread " + mAppThread.asBinder());
                  synchronized(ActivityManagerService.this) {
                      **appDiedLocked(mApp, mPid, mAppThread, true, null);**
                  }
              }
      }
      

      绑定application的时候会zhuceIApplicationThread的死亡回调—这里只是Binder死亡,然后通过appDiedLocked杀死进程,并调整进程优先级

    • 例如当service启动时,进程无效,进程存在问题的时候,会通过AMS#appDiedLocked方法杀死进程

      frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

      private void realStartServiceLocked(ServiceRecord r, ProcessRecord app,
                  IApplicationThread thread, int pid, UidRecord uidRecord, boolean execInFg,
                  boolean enqueueOomAdj) throws RemoteException {
      				// 服务启动流程里
      				try {
                  ...
                  created = true;
              } catch (DeadObjectException e) {
                  Slog.w(TAG, "Application dead when creating service " + r);
                  **mAm.appDiedLocked(app, "Died when creating service");**
                  throw e;
              }
      
      }
      

      在服务启动流程中,如果发现了DeadObjectException异常,则会通过ASM去杀进程,意思是服务创建过程中,Application死亡,主进程不存在的情况——这里又在想,主进程都死亡了,还去杀进程干啥?非也非也,进程被杀了也需要进行清理动作,进程从Lru移除等动作

    • 例如当ContentProvider不稳定出现异常的情况,会通过AMS#appDiedLocked方法杀死进程

      frameworks/base/services/core/java/com/android/server/am/ContentProviderHelper.java

      void unstableProviderDied(IBinder connection) {
      						// 尝试pingBinder,检查binder是否存活,是否具有连通性
      						// 如果仍然ping得通,则不杀该进程
                  if (provider.asBinder().pingBinder()) {
                      // Er, no, still looks good to us.
                      synchronized (mService) {
                          Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
                                  + " says " + conn + " died, but we don't agree");
                          return;
                      }
                  }
      						// 走到这说明进程已经dead了,通过AMS杀进程,并调整进程优先级和做清理动作
                  mService.appDiedLocked(proc, "unstable content provider");
      
      }
      

      unstableProviderDied方法的作用就是清理不稳定的ContentProvider,官方回答:从已知的提供者映射中删除垂死的提供者

    • 例如当APP应用程序启动时,在ATMS#realStartActivityLocked中本来是要准备回调activity的生命周期的,但是发生了RemoteException远程调用异常,则会通过AMS#appDiedLocked方法杀死进程:proc.appDied(“2nd-crash”);

      应用启动流程会执行该方法,进程存在的时候会执行到这里来,frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java

      boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
                  boolean andResume, boolean checkConfig) throws RemoteException {
      						try {
      								// 准备执行Activity的生命周期和启动Activity
      								// Create activity launch transaction.
                      final ClientTransaction clientTransaction = ClientTransaction.obtain(
                              proc.getThread(), r.appToken);
      
                      final boolean isTransitionForward = r.isTransitionForward();
                      clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                              System.identityHashCode(r), r.info,
                              // TODO: Have this take the merged configuration instead of separate global
                              // and override configs.
                              mergedConfiguration.getGlobalConfiguration(),
                              mergedConfiguration.getOverrideConfiguration(), r.compat,
                              r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
                              proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
                              results, newIntents, r.takeOptions(), isTransitionForward,
                              proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                              r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
                              r.getLaunchedFromBubble()));
      
                      // Set desired final state.
                      final ActivityLifecycleItem lifecycleItem;
                      if (andResume) {
                          lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
                      } else {
                          lifecycleItem = PauseActivityItem.obtain();
                      }
                      clientTransaction.setLifecycleStateRequest(lifecycleItem);
      
                      // Schedule transaction.
                      mService.getLifecycleManager().scheduleTransaction(clientTransaction);
      						}catch (RemoteException e) {
                      if (r.launchFailed) {
                          // This is the second time we failed -- finish activity and give up.
                          Slog.e(TAG, "Second failure launching "
                                  + r.intent.getComponent().flattenToShortString() + ", giving up", e);
                          **proc.appDied("2nd-crash");**
                          r.finishIfPossible("2nd-crash", false /* oomAdj */);
                          return false;
                      }
      
                      // This is the first time we failed -- restart process and
                      // retry.
                      r.launchFailed = true;
                      proc.removeActivity(r, true /* keepAssociation */);
                      throw e;
                  }
              }
      
      }
      

      proc.appDied(“2nd-crash”);会去调用AMS#appDiedLocked,然后更新进程状态和优先级

    • AMS#appDiedLocked分析

       		@GuardedBy("this")
          final void appDiedLocked(ProcessRecord app, String reason) {
              appDiedLocked(app, app.getPid(), app.getThread(), false, reason);
          }
      
          @GuardedBy("this")
          final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
                  boolean fromBinderDied, String reason) {
              // First check if this ProcessRecord is actually active for the pid.
              final ProcessRecord curProc;
              ...
              if (!app.isKilled()) {
                  ...
      						// 杀死整个进程组,uid一样的进程,因为一个app可能会启动另外一个进程,它们都属于一个进程组
                  ProcessList.killProcessGroup(app.uid, pid);
                  synchronized (mProcLock) {
                      app.setKilled(true);
                  }
              }
      
              ...
      
                  // app死亡也会调整进程adj
                  if (doOomAdj) {
                      **updateOomAdjLocked**(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
                  }
                 ...
          }
      
  • 通过AMS#setProcessImportant也会调整进程优先级

    如果调用了setProcessImportant则代表会将这个进程视为重要的进程(可手动调用进行客制化),优先级会被提高

    		@Override
        public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
            enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
                    "setProcessImportant()");
            synchronized(this) {
                boolean changed = false;
    
                ProcessRecord pr = null;
                synchronized (mPidsSelfLocked) {
                    ...
                    if (isForeground && token != null) {
                        ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
                            @Override
                            public void binderDied() {
    														// Binder死亡回调,也会调整oom进程优先级
                                **importanceTokenDied**(this);
                            }
                        };
                        try {
                            token.linkToDeath(newToken, 0);
                            mImportantProcesses.put(pid, newToken);
                            pr.mState.setForcingToImportant(newToken);
                            changed = true;
                        } catch (RemoteException e) {
                            // If the process died while doing this, we will later
                            // do the cleanup with the process death link.
                        }
                    }
                }
    
                if (changed) {
                    **updateOomAdjLocked(pr, OomAdjuster.OOM_ADJ_REASON_UI_VISIBILITY);**
                }
            }
        }
    
  • 应用进程启动时,ProcessRecord创建后,也会调整(ActivityThread进程还没被fork出来)

    例如是持久进程,如果被杀后,进程重启也会用这个方法,会继续调用final ProcessRecord addAppLocked启动进程

     		@GuardedBy("this")
        final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
                boolean disableHiddenApiChecks, boolean disableTestApiChecks,
                String abiOverride, int zygotePolicyFlags) {
            ProcessRecord app;
            if (!isolated) {
                app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
                        info.uid);
            } else {
                app = null;
            }
    
            if (app == null) {
                // 进程启动流程
                app = mProcessList.newProcessRecordLocked(info, customProcess, isolated, 0,
                        new HostingRecord("added application",
                            customProcess != null ? customProcess : info.processName));
                // 调整进程lru
                updateLruProcessLocked(app, false, null);
                // 调整进程oom adj优先级
                **updateOomAdjLocked**(app, OomAdjuster.OOM_ADJ_REASON_PROCESS_BEGIN);
            }
    
           ...
    
            // 应用启动流程也会调整oom adj优先级
            // 如果application中带有PERSISTENT_MASK标签,则为持久进程,该进程优先级会比较高:-800
            // 不过必须是带有system_uid标签的进程才行:ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT;
            if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
                app.setPersistent(true);
                app.mState.setMaxAdj(ProcessList.PERSISTENT_PROC_ADJ);
            }
            if (app.getThread() == null && mPersistentStartingProcesses.indexOf(app) < 0) {
                mPersistentStartingProcesses.add(app);
    						// 继续启动进程
                mProcessList.startProcessLocked(app, new HostingRecord("added application",
                        customProcess != null ? customProcess : app.processName),
                        zygotePolicyFlags, disableHiddenApiChecks, disableTestApiChecks,
                        abiOverride);
            }
    
            return app;
        }
    
  • 屏幕被唤醒时调整

    void onWakefulnessChanged(int wakefulness) {
            synchronized (this) {
                boolean wasAwake = mWakefulness.getAndSet(wakefulness)
                        == PowerManagerInternal.WAKEFULNESS_AWAKE;
                boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
    
                if (wasAwake != isAwake) {
                    // Also update state in a special way for running foreground services UI.
                    mServices.updateScreenStateLocked(isAwake);
                    reportCurWakefulnessUsageEvent();
                    mActivityTaskManager.onScreenAwakeChanged(isAwake);
                    mOomAdjProfiler.onWakefulnessChanged(wakefulness);
                }
                **updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_UI_VISIBILITY);**
            }
        }
    
  • setHasTopUi时调整—-也就是存在下拉状态,通知栏

    @Override
        public void setHasTopUi(boolean hasTopUi) throws RemoteException {
            updateOomAdjLocked(pr, OomAdjuster.OOM_ADJ_REASON_UI_VISIBILITY);
        }
    
  • AMS调用trimApplicationsLocked时调整—代表Empty进程被杀的情况
    该方法被调用,代表进程状态为Empty或者cache,然后超过了16个进程,会走到这被kill

     		@GuardedBy("this")
        private void trimApplicationsLocked(boolean forceFullOomAdj, String oomAdjReason) {
            // First remove any unused application processes whose package
            // has been removed.
            boolean didSomething = false;
            for (int i = mProcessList.mRemovedProcesses.size() - 1; i >= 0; i--) {
                final ProcessRecord app = mProcessList.mRemovedProcesses.get(i);
                    ...
                    if (pid > 0 && pid != MY_PID) {
                        app.killLocked("empty",
                                ApplicationExitInfo.REASON_OTHER,
                                ApplicationExitInfo.SUBREASON_TRIM_EMPTY,
                                false);
                    } else if (thread != null) {
                        try {
                            thread.scheduleExit();
                        } catch (Exception e) {
                            // Ignore exceptions.
                        }
                    }
                    didSomething = true;
                    cleanUpApplicationRecordLocked(app, pid, false, true, -1, false /*replacingPid*/,
                            false /* fromBinderDied */);
                    mProcessList.mRemovedProcesses.remove(i);
    								// 如果是持久进程,则进行重启进程
                    if (app.isPersistent()) {
                        addAppLocked(app.info, null, false, null /* ABI override */,
                                ZYGOTE_POLICY_FLAG_BATCH_LAUNCH);
                    }
                }
            }
    
            // Now update the oom adj for all processes. Don't skip this, since other callers
            // might be depending on it.
            if (didSomething || forceFullOomAdj) {
                **updateOomAdjLocked**(oomAdjReason);
            }
        }
    

**以下调整都是通过ATMS#updateOomAdj-->AMS#LocalService#updateOomAdj进行调整——**最终都是走到AMS#updateOomAdjLocked进行调整

  • 主动调用finish()时会调用/清理任务栈时会调用,主动调用过finishIfPossible(代表主动finish进程,理由有很多)会调整,具体不分析了,ActivityRecord或ActivityClientControll或Task,会调用这个方法

**以下调整都是通过ProcessRecord#updateProcessInfo进行调整——**最终都是走到AMS#updateOomAdjLocked进行调整

  • 应用进程热启动时(也可以算冷启动,因为冷启动过后就会走热启动的一些流程),也会调整(ActivityTaskSupervisor.java#realStartActivityLocked)

    frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java

    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
                boolean andResume, boolean checkConfig) throws RemoteException {
    				...
    				r.launchFailed = false;
    
           
            if (andResume && readyToResume()) {
                ...
            } else {
                ...
                r.setState(PAUSED, "realStartActivityLocked");
                mRootWindowContainer.executeAppTransitionForAllDisplay();
            }
            ...
            // 应用启动过程,这里面会去调整进程优先级
    				// proc就是:WindowProcessController,r就是ActivityRecord
    				// **mTopProcessState就是:**ActivityManager.PROCESS_STATE_TOP
            **proc.onStartActivity(mService.mTopProcessState, r.info);**
    
    }
    

    调用了WPC的onStartActivity,可以看到传递的mService.mTopProcessState就是ActivityManager.PROCESS_STATE_TOP,代表应用启动后默认是PROCESS_STATE_TOP进程状态

    frameworks/base/services/core/java/com/android/server/wm/WindowProcessController.java

    void onStartActivity(int topProcessState, ActivityInfo info) {
    				// 这个方法是在ActivityTaskSupervisor调用过来的(realStartActivityLocked),代表应用启动过程--也是activity启动过程
            // topProcessState参数就是ActivityManager.PROCESS_STATE_TOP
            String packageName = null;
            ...
            // update ActivityManagerService.PendingStartActivityUids list.
    				// 为true,将该进程的uid和pid存入AMS的mPendingStartActivityUids中
            if (topProcessState == ActivityManager.PROCESS_STATE_TOP) {
                mAtm.mAmInternal.addPendingTopUid(mUid, mPid);
            }
    
    				// 为调整oomAdj做准备,此时还没有调整
            // 这个方法主要就是为Task按z-oder排序,然后计算Activity状态
            // 例如是否可见,是否处于停止状态,ACTIVITY_STATE_FLAG_IS_VISIBLE(可见),pausing,resumed等状态
            prepareOomAdjustment();
            // 调用实现了WindowProcessListener接口对象的onStartActivity方法,并传递了topProcessState
    				// ProcessRecord就实现了这个接口,所以继续看ProcessRecord#onStartActivity
            final Message m = PooledLambda.obtainMessage(**WindowProcessListener::onStartActivity**,
                    mListener, **topProcessState**, shouldSetProfileProc(), packageName,
                    info.applicationInfo.longVersionCode);
            mAtm.mH.sendMessageAtFrontOfQueue(m);
        }
    

    frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java

      	@Override
        public void onStartActivity(int topProcessState, boolean setProfileProc, String packageName,
                long versionCode) {
    				// 以AMS为锁,topProcessState:ActivityManager.PROCESS_STATE_TOP
            synchronized (mService) {
                mWaitingToKill = null;
                ...
                if (packageName != null) {
                    addPackage(packageName, versionCode, mService.mProcessStats);
                }
    
                // 更新进程adj优先级
                // Update oom adj first, we don't want the additional states are involved in this round.
                **updateProcessInfo**(false /* updateServiceConnectionActivities */,
                        true /* activityChange */, **true** /* updateOomAdj */);
                setPendingUiClean(true);
    						// activity启动流程默认是有UI状态的
                mState.setHasShownUi(true);
    						// 并且强制将进程状态设置为:ActivityManager.PROCESS_STATE_TOP
    						// mSate就是:ProcessStateRecord
                mState.forceProcessStateUpTo(topProcessState);
            }
        }
    

    总结一下流程:

    1. ActivityTaskSupervisor#realStartActivityLocked中正在进行activity的启动流程,并且调用了WindowProcessController.onStartActivity,然后传递的参数是ActivityManager.PROCESS_STATE_TOP,意思是activity启动时,会将该进程状态设置为PROCESS_STATE_TOP
    2. 然后调用了WindowProcessController里的prepareOomAdjustment(),意在遍历所有Task,给该进程的Activity设置状态,例如*ACTIVITY_STATE_FLAG_IS_VISIBLEACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASKACTIVITY_STATE_FLAG_HAS_RESUMEDACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSEDACTIVITY_STATE_FLAG_IS_STOPPING*等,可以判断Activity是否处于前台等,是否resumed等(hasResumedActivity
    3. 然后进入了ProcessRecord的onStartActivity方法,更新进程的adj优先级和进程状态,不管进程状态更新到何等状态,会调用ProcessStateRecord.forceProcessStateUpTo强制变为PROCESS_STATE_TOP,因为activity启动时默认就必须是这个进程状态
  • 应用进程热启动时(也可以算冷启动,因为冷启动过后就会走热启动的一些流程),也会调整—补充(Task.java#resumeTopActivityInnerLocked)

    frameworks/base/services/core/java/com/android/server/wm/Task.java

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
                boolean deferPause) {
    				// 如果上个activity处于pausing状态
    				// 这里的意思就是将上个activityRecord置为STOPPING或finishing或PAUSED---调用了activityPaused
    				boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
            if (mResumedActivity != null) {
    						// 同pauseBackTasks,最终也用调用到startPausingLocked
                pausing |= startPausingLocked(false /* uiSleeping */, next,
                        "resumeTopActivityInnerLocked");
            }
    				// 如果上个activity处于pausing状态,则会进入到这个分支
    				// activity启动流程就是需要将上一个activity pausing,所以这个方法会执行两次,第一次pausing为true,第二次为false
    				// 实在的说,是将所有(除当前activity)的所有activity都执行pausing
            if (pausing) {
                ...
    						// 如果当前activity的进程存在,也就是调用过ActivityRecord的setProcess和WPC绑定过,并且ActivityThread存在
                if (next.attachedToProcess()) {
    								// 没有调整进程优先级和进程状态,而是调整进程的Lru近期使用情况,因为updateOomAdj参数为false
                    **next.app.updateProcessInfo(**false /* updateServiceConnectionActivities */,
                            true /* activityChange */, **false** /* updateOomAdj */,
                            false /* addPendingTopUid */);
                } else if (!next.isProcessRunning()) {// 进程不存在的时候,调用startProcessAsync去fork进程
                    final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
                    mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
                            isTop ? "pre-top-activity" : "pre-activity");
                }
                if (lastResumed != null) {
                    lastResumed.setWillCloseOrEnterPip(true);
                }
                return true;
            } ...
    
    }
    

    由上可知,在启动的activity进程存在的时候,并且上个activity正在pausing的时候,会更新进程信息,但不会更新进程状态和adj,因为updateOomAdj参数为false

  • ActivityRecord生命周期发生变化时,也会调整

你可能感兴趣的:(Android开发旅途,android,gitee,aosp,java)