Interprétation détaillée d'Android oom_adj

Code source basé sur : Android R

0. Préface

Dans le billet de blog "Analyse de l'algorithme de niveau d'eau de la mémoire oom_adj", la méthode de calcul et d'utilisation du niveau d'eau de la mémoire oom_adj dans lmkd est analysée en détail. Dans le billet de blog "Principe de mise à jour oom_adj (1)" et "Principe de mise à jour oom_adj (2 )", le système Android est analysé en détail. Le principe de mise à jour de oom_adj est analysé en détail. Grâce à ces quelques articles de blog, nous comprenons mieux oom_adj.

Sur la base du billet de blog précédent, cet article analyse les détails du code et interprète la valeur de chaque oom_adj en détail.

1. niveau ajusté

Tout d'abord, comme dans les articles de blog précédents, listons les valeurs de oom_adj. Ce qui suit expliquera la valeur de chaque oom_adj individuellement. 

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

Niveau d'ajustement valeur illustrer
UNKNOWN_ADJ 1001 Utilisé à des endroits spécifiques, fait généralement référence au processus de cache, la valeur exacte n'est pas connue
CACHED_APP_MAX_ADJ 999 La valeur maximale des processus invisibles, qui peuvent être tués sans aucune interférence
CACHED_APP_LMK_FIRST_ADJ 950 oom_adj Le premier niveau autorisé à être tué ne peut pas être égal à CACHED_APP_MAX_ADJ
CACHED_APP_MIN_ADJ 900 Valeur minimale pour les processus invisibles
SERVICE_B_ADJ 800 Service dans la liste B (plus ancien, moins susceptible d'être utilisé)
PREVIOUS_APP_ADJ 700 Le processus de l'application précédente (souvent en appuyant sur la touche retour)
HOME_APP_ADJ 600 Processus à domicile
SERVICE_ADJ 500 processus de service d'application, le tuer n'aura généralement pas beaucoup d'impact
HEAVY_WEIGHT_APP_ADJ 400 Le processus lourd en arrière-plan, démarrage dans le fichier system/rootdir/init.rc
BACKUP_APP_ADJ 300 Sauvegardez le processus, le tuer n'est pas vraiment fatal mais mauvais
PERCEPTIBLE_LOW_APP_ADJ 250 Les processus liés aux utilisateurs ou aux systèmes sont plus importants que les services, mais s'ils sont supprimés, ils n'affecteront pas immédiatement les sens du client.
PERCEPTIBLE_APP_ADJ 200 Processus perceptibles, tels que la lecture de musique de fond
VISIBLE_APP_ADJ 100 processus visuel
PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ 50 récemment processus TOP
FOREGROUND_APP_ADJ 0 processus de premier plan
PERSISTENT_SERVICE_ADJ -700 Un processus associé au système ou un processus résident
PERSISTENT_PROC_ADJ -800

Processus résidents du système, tels que la téléphonie

Certainement pas destiné à tuer, mais pas complètement mortel

SYSTÈME_ADJ -900 Processus système
NATIVE_ADJ -1000 Le processus natif n'est pas géré par le système, il n'y a donc pas d'adaptation oom_adj

2. ADJ <0

Dans la classification adj, la valeur de FOREGROUND_APP_ADJ est 0 et le processus propriétaire de l'adj est le processus de premier plan. Le système considère les processus dont la valeur est inférieure à 0 comme des processus importants dans le système. comme suit:

  • NATIVE_ADJ(-1000) : il s'agit d'un processus natif dérivé du processus d'initialisation et n'est pas contrôlé par le système ;
  • SYSTEM_ADJ(-900) : fait référence au processus system_server ;
  • PERSISTENT_PROC_ADJ(-800) : fait référence au processus système (c'est-à-dire avec la balise FLAG_SYSTEM) qui déclare android:persistent comme étant vrai dans AndroidManifest.xml. Un processus persistant ne sera pas tué dans des circonstances normales. Même s'il est tué ou qu'un crash se produit, le système redémarrera immédiatement le processus ;
  • PERSISTENT_SERVICE_ADJ(-700) : C'est un processus démarré par la fonction startIsolatedProcess(), ou un processus de service lié par le system_server ou un processus persistant (et avec BIND_ABOVE_CLIENT ou BIND_IMPORTANT) ;

2.1 SYSTEM_ADJ(-900)

SYSTEM_ADJ fait uniquement référence au processus system_server. AMS.setSystemProcess() est appelé pendant SystemServer.startBootstrapServices(), et le maxAdj de system_server est défini sur SYSTEM_ADJ dans cette fonction :

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

    public void setSystemProcess() {
        try {
            ...

            synchronized (this) {
                ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
                        false,
                        0,
                        new HostingRecord("system"));
                app.setPersistent(true);
                app.pid = app.mPidForCompact = MY_PID;
                app.getWindowProcessController().setPid(MY_PID);
                app.maxAdj = ProcessList.SYSTEM_ADJ; //----这里设定system_server 的 maxAdj
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                addPidLocked(app);
                mProcessList.updateLruProcessLocked(app, false, null);
                updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
            }
        }
        ...
    }

Lors de l'appel de la fonction updateOomAdjLocked(), un paramètre est transmis. DecomputeOomAdjLocked() dans le billet de blog "oom_adj Update Principle (2)" :

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

if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
    ...
    app.curAdj = app.maxAdj;
    ...
}

L'adj du processus final system_server est défini sur -900, ce qui peut également être vu à partir de dumpsys meminfo :

    153,028K: System
        153,028K: system (pid 1143 / adj -900)

2.2 PERSISTENT_PROC_ADJ(-800)

Le processus PERSISTENT_PROC_ADJ doit déclarer le processus système (avec FLAG_SYSTEM) avec l'attribut android:persistent comme true dans AndroidManifest.xml , également connu sous le nom de processus persistant. Les processus persistants ne seront pas interrompus dans des circonstances normales. Une fois arrêtés ou en cas de crash, le système redémarrera immédiatement le processus.

Définir l'emplacement :

  • Liste de processus . newProcessRecordLocked();
  • AMS . addAppLocked();

newProcessRecordLocked() sera appelé lors du processus de démarrage d'une nouvelle application , y compris même le processus system_server, comme la fonction setSystemProcess() mentionnée dans la section précédente :

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

    public void setSystemProcess() {
        try {
            ...

            synchronized (this) {
                ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
                        false,
                        0,
                        new HostingRecord("system"));
                app.setPersistent(true);
                app.pid = app.mPidForCompact = MY_PID;
                app.getWindowProcessController().setPid(MY_PID);
                app.maxAdj = ProcessList.SYSTEM_ADJ; //----这里设定system_server 的 maxAdj
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                addPidLocked(app);
                mProcessList.updateLruProcessLocked(app, false, null);
                updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
            }
        }
        ...
    }

La première phrase du code consiste à créer un objet ProcessRecord via  la fonction newProcessRecordLocked() .

 Jetons un coup d'oeil à cette fonction :

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

    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
            boolean isolated, int isolatedUid, HostingRecord hostingRecord) {
        String proc = customProcess != null ? customProcess : info.processName;
        final int userId = UserHandle.getUserId(info.uid);
        int uid = info.uid;
        if (isolated) {
            ...
        }
        final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);

        if (!mService.mBooted && !mService.mBooting
                && userId == UserHandle.USER_SYSTEM
                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
            // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
            r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
            r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
            r.setPersistent(true);
            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
        }
        if (isolated && isolatedUid != 0) {
            // Special case for startIsolatedProcess (internal only) - assume the process
            // is required by the system server to prevent it being killed.
            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
        }
        addProcessNameLocked(r);
        return r;
    }

La fonction sait qu'il sera défini sur PERSISTENT_PROC_ADJ uniquement au démarrage de system_server , mais à la fin de setSystemProcess(), le maxAdj de system_server sera remplacé par SYSTEM_ADJ.

Si le processus est isolé, maxAdj sera défini sur PERSISTENT_SERVICE_ADJ. Veuillez consulter la section 2.3 pour plus de détails .

Regardons une autre fonction addAppLocked() :

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

    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
            boolean disableHiddenApiChecks, boolean disableTestApiChecks,
            boolean mountExtStorageFull, String abiOverride, int zygotePolicyFlags) {
        ProcessRecord app;
        if (!isolated) {
            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
                    info.uid, true);
        } else {
            app = null;
        }

        if (app == null) {
            app = mProcessList.newProcessRecordLocked(info, customProcess, isolated, 0,
                    new HostingRecord("added application",
                            customProcess != null ? customProcess : info.processName));
            mProcessList.updateLruProcessLocked(app, false, null);
            updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_PROCESS_BEGIN);
        }

        ...

        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
            app.setPersistent(true);
            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
        }
        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
            mPersistentStartingProcesses.add(app);
            mProcessList.startProcessLocked(app, new HostingRecord("added application",
                    customProcess != null ? customProcess : app.processName),
                    zygotePolicyFlags, disableHiddenApiChecks, disableTestApiChecks,
                    mountExtStorageFull, abiOverride);
        }

        return app;
    }

Lorsque l'indicateur d'application est défini sur FLAG_SYSTEM | FLAG_PERSISTENT, la valeur de maxAdj est définie sur PERSISENT_PROC_ADJ.

Lorsque SystemServer démarre startOtherServices(), AMS.systemReady() sera appelé pour terminer la phase de démarrage. startPersistentApps() sera appelé ici :

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

    void startPersistentApps(int matchFlags) {
        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;

        synchronized (this) {
            try {
                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
                for (ApplicationInfo app : apps) {
                    if (!"android".equals(app.packageName)) {
                        addAppLocked(app, null, false, null /* ABI override */,
                                ZYGOTE_POLICY_FLAG_BATCH_LAUNCH);
                    }
                }
            } catch (RemoteException ex) {
            }
        }
    }

Ici, le processus persistant du système est chargé et la fonction addAppLocked() est appelée.

2.3 PERSISTENT_SERVICE_ADJ(-700)

Le processus de PERSISTENT_SERVICE_ADJ est un processus démarré par startIsolatedProcess(), ou un processus de service lié par system_server ou un processus persistant.

Nous avons mentionné dans l' article précédent  newProcessRecordLocked() que lorsque le processus est isolé, maxAdj sera défini sur PERSISTENT_SERVICE_ADJ et le processus déclenché par newProcessRecordLocked() est le suivant :

AMS.startIsolatedProcess() -> ProcessList.startProcessLocked() ->newProcessRecordLocked()

L'autre consiste à appeler calculateOomAdjLocked() dans updateOomAdjLocked() :

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

    private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj,
            ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
            boolean computeClients) {
        ...

        int capabilityFromFGS = 0; // capability from foreground service.
        for (int is = app.numberOfRunningServices() - 1;
                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
                        || procState > PROCESS_STATE_TOP);
                is--) {
            ServiceRecord s = app.getRunningServiceAt(is);
            ...
            
            ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = s.getConnections();
            for (int conni = serviceConnections.size() - 1;
                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
                            || procState > PROCESS_STATE_TOP);
                    conni--) {
                ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni);
                for (int i = 0;
                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
                                || procState > PROCESS_STATE_TOP);
                        i++) {
                    ...

                    int clientAdj = client.getCurRawAdj();
                    int clientProcState = client.getCurRawProcState();

                    if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) {
                        ...
                        if (adj > clientAdj) {
                            if (app.hasShownUi && !app.getCachedIsHomeProcess()
                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
                                    adjType = "cch-bound-ui-services";
                                }
                            } else {
                                int newAdj;
                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
                                        |Context.BIND_IMPORTANT)) != 0) {
                                    if (clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
                                        newAdj = clientAdj;
                                    } else {
                                        newAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
                                       ...
                                    }
                                }

Lorsque le processus actuel est lié à un client et que la priorité adj du processus actuel n'est pas aussi élevée que la priorité du client, déterminez si les indicateurs BIND_ABOVE_CLIENT ou BIND_IMPORTANT sont définis.

3. FOREGROUND_APP_ADJ(0)

Scénario 1 : les processus qui remplissent l'une des conditions suivantes appartiennent à la priorité FOREGROUND_APP_ADJ(0) :

  • Activité en état de reprise
  • Un service qui exécute un rappel de cycle de vie (comme l'exécution de onCreate, onStartCommand, onDestroy, etc.)
  • BroadcastReceiver exécutant onReceive()
  • Processus démarré via startInstrumentation()

Pour le code détaillé, veuillez consulter calculateOomAdjLocked() dans  le billet de blog « oom_adj Update Principe (2) » :

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

    private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj,
            ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
            boolean computeClients) {
        ...

        boolean foregroundActivities = false;
        if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == topApp) {
            // The last app on the list is the foreground app.
            adj = ProcessList.FOREGROUND_APP_ADJ;
            ...
        } else if (app.runningRemoteAnimation) {
            adj = ProcessList.VISIBLE_APP_ADJ;
            ...
        } else if (app.getActiveInstrumentation() != null) {
            adj = ProcessList.FOREGROUND_APP_ADJ;
            ...
        } else if (app.getCachedIsReceivingBroadcast(mTmpBroadcastQueue)) {
            adj = ProcessList.FOREGROUND_APP_ADJ;
            ...
        } else if (app.executingServices.size() > 0) {
            adj = ProcessList.FOREGROUND_APP_ADJ;
            ...
        } else if (app == topApp) {
            adj = ProcessList.FOREGROUND_APP_ADJ;
            ...
        } else {
            procState = PROCESS_STATE_CACHED_EMPTY;
            ...
        }

Scénario 2 :  lorsque la méthode bindService() est appelée dans l'activité du processus client, les indicateurs contiennent le paramètre BIND_ADJUST_WITH_ACTIVITY et l'activité est visible, alors le processus de service actuel appartient également au processus de premier plan. Le code source est le suivant :

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

    private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj,
            ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
            boolean computeClients) {

            ...

                    final ActivityServiceConnectionsHolder a = cr.activity;
                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ
                                && a.isActivityVisible()) {
                            adj = ProcessList.FOREGROUND_APP_ADJ;
                            app.setCurRawAdj(adj);

Scénario 3 :  Pour le processus fournisseur, il existe deux conditions suivantes pour devenir un processus de premier plan :

  • Lorsque le client du fournisseur traite ADJ<=FOREGROUND_APP_ADJ, le processus fournisseur ADJ est égal à FOREGROUND_APP_ADJ
  • Lorsque le fournisseur a une dépendance de processus externe (non-framework), c'est-à-dire que la méthode getContentProviderExternal() est appelée, alors ADJ est au moins égal à FOREGROUND_APP_ADJ

4. VISIBLE_APP_ADJ (100)

Processus visible : lorsque ActivityRecord est visible = true, il s'agit du processus visible par l'activité.

À partir d'Android P, le niveau ADJ est encore affiné et VISIBLE_APP_LAYER_MAX (99) est ajouté  , ce qui signifie qu'il y a 99 emplacements entre VISIBLE_APP_ADJ (100) et PERCEPTIBLE_APP_ADJ (200). La plage de valeurs du niveau visible ADJ est [100 199]. L'algorithme ajustera son ADJ en fonction du mLayerRank de la tâche où il se trouve. 100 plus mLayerRank équivaut à l'ADJ cible. Plus la couche est grande, plus l'ADJ est petit.

La méthode de calcul de mLayerRank de TaskRecord consiste à appeler la méthode RankTaskLayersIfNeeded() d'ASS dans le processus updateOomAdjLocked().

Lorsque l'ActivityRecord en haut du TaskRecord est vide, terminé ou invisible, définissez le mLayerRank du TaskRecord égal à -1 ; le baseLayer de chaque ActivityDisplay commence à 0, en commençant par le TaskRecord supérieur, le premier ADJ = 100, à partir de Add. 1 de haut en bas jusqu’à ce que 199 soit la limite supérieure.

5. PERCEPTIBLE_APP_ADJ (200)

Processus perceptible : lorsque le processus a une activité invisible, mais que l'activité est dans les états PAUSING, PAUSED ou STOPPING, elle est PERCEPTIBLE_APP_ADJ.

Il existe également des calculs spéciaux pour les processus conscients dans la fonction calculateOomAdjLocked  () :

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

    private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj,
            ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
            boolean computeClients) {

        ...

        /********* 场景 1 **********/
        // Examine all activities if not already foreground.
        if (!foregroundActivities && app.getCachedHasActivities()) {
            app.computeOomAdjFromActivitiesIfNecessary(mTmpComputeOomAdjWindowCallback,
                    adj, foregroundActivities, procState, schedGroup, appUid, logUid,
                    PROCESS_STATE_CUR_TOP);

            adj = app.mCachedAdj;
            ...
        }

        ...

        /********* 场景 2 **********/
        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
                || procState > PROCESS_STATE_FOREGROUND_SERVICE) {
            if (app.hasForegroundServices()) {
                // The user is aware of this app, so make it visible.
                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                procState = PROCESS_STATE_FOREGROUND_SERVICE;
                app.adjType = "fg-service";
                app.setCached(false);
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
            } else if (app.hasOverlayUi()) {
                // The process is display an overlay UI.
                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                procState = PROCESS_STATE_IMPORTANT_FOREGROUND;
                app.setCached(false);
                app.adjType = "has-overlay-ui";
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
            }
        }

        ...

        /********* 场景 3 **********/
        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
                || procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
            if (app.forcingToImportant != null) {
                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
                app.setCached(false);
                app.adjType = "force-imp";
                app.adjSource = app.forcingToImportant;
                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
            }
        }

Scénario 1 : S'il ne s'agit pas d'un processus de premier plan et que des activités de cache existent, vous devez continuer à déterminer l'ajustement.

Appelez calculateOomAdjFromActivitiesIfNecessary(). Ici, lors du calcul de oom_adj, un rappel est transmis et la fenêtre est utilisée pour confirmer si l'activité est dans l'état visible, en PAUSING, STOPPING ou dans d'autres états, et la fonction de rappel correspondant au rappel est appelée en fonction à l'État.

  • visible : si adj est supérieur à VISIBLE_APP_ADJ, il sera ramené à VISIBLE_APP_ADJ ;
  • PAUSING : si adj est supérieur à PERCEPTIBLE_APP_ADJ, il sera ramené à PERCEPTIBLE_APP_ADJ ;
  • ARRÊT : si adj est supérieur à PERCEPTIBLE_APP_ADJ, il sera ramené à PERCEPTIBLE_APP_ADJ ;

Scénario 2 : le processus dispose de services de premier plan ou le processus utilise une interface utilisateur superposée

La condition préalable à l'ajustement des prix est que l'importance du processus soit tombée en dessous du niveau perceptible ou que le niveau d'état du processus soit supérieur à celui du service de premier plan.

Pour avoir des services de premier plan, exécutez la fonction startForegroundService() ;

hasOverlayUi() est vrai, indiquant que l'interface utilisateur de non-activité se trouve en haut de l'écran, comme une fenêtre avec le type d'affichage TYPE_APPLICATION_OVERLAY.

Scénario 3 : le processus forcerToImportant n'est pas vide

Cette valeur n'est pas nulle, indiquant que la fonction setProcessImportant() a été exécutée, comme le processus contextuel Toast ;

6. BACKUP_APP_ADJ (300)

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

    private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj,
            ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
            boolean computeClients) {

        ...

        final BackupRecord backupTarget = mService.mBackupTargets.get(app.userId);
        if (backupTarget != null && app == backupTarget.app) {
            // If possible we want to avoid killing apps while they're being backed up
            if (adj > ProcessList.BACKUP_APP_ADJ) {
                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
                adj = ProcessList.BACKUP_APP_ADJ;
                if (procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
                    procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
                }
                app.adjType = "backup";
                app.setCached(false);
            }
            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
                procState = ActivityManager.PROCESS_STATE_BACKUP;
                app.adjType = "backup";
            }
        }

La condition préalable est que backupTarget ne soit pas vide :

  • Exécutez le processus bindBackupAgent() et définissez la valeur mBackupTarget ;
  • Exécutez le processus clearPendingBackup() ou unbindBackupAgent() et videz la valeur mBackupTarget ;

7. HEAVY_WEIGHT_APP_ADJ (400)

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

    private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj,
            ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
            boolean computeClients) {

        ...

        //重量级后台进程,把adj和proc_state都拉回到 heavy weight水平
        if (app.getCachedIsHeavyWeight()) {
            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
                // We don't want to kill the current heavy-weight process.
                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
                app.setCached(false);
                app.adjType = "heavy";
            }
            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
                app.adjType = "heavy";
            }
        }
  • processus realStartActivityLocked(), lorsque le privateFlags de l'application identifie PRIVATE_FLAG_CANT_SAVE_STATE, définissez la valeur mHeavyWeightProcess ;
  • finishHeavyWeightApp(), valeur mHeavyWeightProcess vide ;

8. HOME_APP_ADJ (600)

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

    private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj,
            ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
            boolean computeClients) {

        ...

        //HOME 进程,将其拉回HOME_APP_ADJ
        if (app.getCachedIsHomeProcess()) {
            if (adj > ProcessList.HOME_APP_ADJ) {
                // This process is hosting what we currently consider to be the
                // home app, so we don't want to let it go into the background.
                adj = ProcessList.HOME_APP_ADJ;
                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
                app.setCached(false);
                app.adjType = "home";
            }
            if (procState > ActivityManager.PROCESS_STATE_HOME) {
                procState = ActivityManager.PROCESS_STATE_HOME;
                app.adjType = "home";
            }
        }

mHomeProcess sera défini lorsqu'une application de type ACTIVITY_TYPE_HOME est démarrée, telle qu'une application de bureau.

9. PREVIOUS_APP_ADJ (700)

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

    private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj,
            ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
            boolean computeClients) {

        ...

        /********* 场景 1 **********/
        if (app.getCachedIsPreviousProcess() && app.getCachedHasActivities()) {
            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
                // This was the previous process that showed UI to the user.
                // We want to try to keep it around more aggressively, to give
                // a good experience around switching between two apps.
                adj = ProcessList.PREVIOUS_APP_ADJ;
                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
                app.setCached(false);
                app.adjType = "previous";
            }
            if (procState > PROCESS_STATE_LAST_ACTIVITY) {
                procState = PROCESS_STATE_LAST_ACTIVITY;
                app.adjType = "previous";
            }
        }

        ...

        /********* 场景 2 **********/
        if (app.lastProviderTime > 0 &&
                (app.lastProviderTime + mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
                adj = ProcessList.PREVIOUS_APP_ADJ;
                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
                app.setCached(false);
                app.adjType = "recent-provider";
            }
            if (procState > PROCESS_STATE_LAST_ACTIVITY) {
                procState = PROCESS_STATE_LAST_ACTIVITY;
                app.adjType = "recent-provider";
            }
        }

Il existe deux scénarios lors de l’utilisation de la fonction calculateOomAdjLocked().

Scénario 1 : le dernier processus utilisé par l'utilisateur qui contient l'interface utilisateur. Afin de donner à l'utilisateur une meilleure expérience de commutation entre les deux applications, l'ADJ du processus précédent est défini au niveau PREVIOUS_APP_ADJ. Lorsque le processus ActivityStoppedLocked() mettra à jour l’application précédente.

Scénario 2 :  lorsque le processus fournisseur est utilisé pour la dernière fois pendant 20 secondes maximum, la priorité n'est pas inférieure à PREVIOUS_APP_ADJ. Le processus fournisseur est une nouvelle logique ajoutée après Android 7.0. L'avantage est d'éviter les turbulences dans le processus propriétaire du fournisseur lorsque la mémoire est relativement faible, c'est-à-dire qu'il est tué après le démarrage puis extrait.

Je suppose que tu aimes

Origine blog.csdn.net/jingerppp/article/details/131717028
conseillé
Classement