• [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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    二. 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();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      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);
              }
      					...
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47

      以上代码主要创建了”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");
              }
      				...
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40

      应用进程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;
                  }
              }
      				...
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      进入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;
                  }
              }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42

      继续分析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);
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29

      以上就是服务的启动过程,前台服务的处理,然后会继续调用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);**
                    }
                }
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
        • 39
        • 40
        • 41
        • 42
        • 43

        绑定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;
                }
        
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14

        在服务启动流程中,如果发现了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");
        
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15

        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;
                    }
                }
        
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
        • 39
        • 40
        • 41
        • 42
        • 43
        • 44
        • 45
        • 46
        • 47
        • 48
        • 49
        • 50
        • 51
        • 52

        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);
                    }
                   ...
            }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
    • 通过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);**
                  }
              }
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
    • 应用进程启动时,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;
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
    • 屏幕被唤醒时调整

      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);**
              }
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • setHasTopUi时调整—-也就是存在下拉状态,通知栏

      @Override
          public void setHasTopUi(boolean hasTopUi) throws RemoteException {
              updateOomAdjLocked(pr, OomAdjuster.OOM_ADJ_REASON_UI_VISIBILITY);
          }
      
      • 1
      • 2
      • 3
      • 4
    • 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);
              }
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38

    **以下调整都是通过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);**
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20

      调用了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);
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22

      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
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23

      总结一下流程:

      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;
              } ...
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33

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

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

  • 相关阅读:
    Java自学(四)————static
    简单函数模拟优化器
    STM32开发(三十一)STM32F103 片内资源 —— 模拟/数字转换 DAC 正弦波 编程详解
    AE duik插件运用-人物行走动画
    PostgreSQL插件的安装使用与删除
    6_显示登录信息以及上传图片
    【Spring底层原理】BeanFactory的实现
    DDD/ABP/EF Core 实现值对象Value Object
    ISP算法----基本DPC算法实现代码
    uni-app 页面跳转动画
  • 原文地址:https://blog.csdn.net/q1210249579/article/details/133516577