AndroidU 进程基础篇(1/2)

一 进程介绍

安卓基于Linux内核,设备开机后,第一个安卓进程为zygote进程,随后fork system_server(上层),其他上层进程需要通过fork system-server进程来创建。因此进程的创建、调度、销毁是进程篇的核心内容。

  • 进程的创建[四大组件通过ams启动进程]
  • 进程的调度[前台进程、后台进程、可见/不可见进程、缓存进程]
  • 当进程查杀[根据进程当前状态来决定查杀内容]

用户打开app/切换app,都希望能够快速的完成这个操作。应用数据未被加载时,进程不存在,需要冷启动。当启动了大量的进程后,系统内存空间吃紧,那么如何查杀进程又是一个问题。因此在进程启动时需要根据启动意图来更新lru进程的重要性,在查杀时有策略的查杀。
这个进程重要性的更新机制就是OomAdjuster


image.png

二 进程调度介绍

oomadj官方文档
https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/am/OomAdjuster.md
重点总结:
The Android OS runs with limited hardware resources, i.e. CPU/RAM/Power. To strive for the better performance, Oom Ajuster is introduced to tweak the following 3 major factors:

  • Process State
    • Wildly used by the System Server, i.e., determine if it's foreground or not, change the GC behavior, etc.
    • Defined in ActivityManager#PROCESS_STATE_*
  • Oom Adj score
    • Used by the lmkd to determine which process should be expunged on memory pressure.
    • Defined in ProcessList#*_ADJ
  • Scheduler Group
    • Used to tweak the process group, thread priorities.
    • Top process is scheduled to be running on a dedicated big core, while foreground processes take the other big cores; background processes stay with LITTLE cores instead.

翻译一下重点在于三个值的更新

  1. 更新进程状态.
[computeOomAdjLSP]
state.setCurProcState(procState);
  1. 更新oom分数.
[computeOomAdjLSP]
state.setCurAdj(adj);
  1. 更新进程所属的进程组.
              switch (curSchedGroup) {
                  case SCHED_GROUP_BACKGROUND:
                      processGroup = THREAD_GROUP_BACKGROUND;
                      break;
                  case SCHED_GROUP_TOP_APP:
                  case SCHED_GROUP_TOP_APP_BOUND:
                      processGroup = THREAD_GROUP_TOP_APP;
                      break;
                  case SCHED_GROUP_RESTRICTED:
                      processGroup = THREAD_GROUP_RESTRICTED;
                      break;
                  default:
                      processGroup = THREAD_GROUP_DEFAULT;
                      break;
              }

4.1 computeOomAdjLSP更新oomadj与procState

        // Do final modification to adj.  Everything we do between here and applying
        // the final setAdj must be done in this function, because we will also use
        // it when computing the final cached adj later.  Note that we don't need to
        // worry about this for max adj above, since max adj will always be used to
        // keep it out of the cached vaues.
        state.setCurAdj(adj);
        state.setCurCapability(capability);
        state.setCurrentSchedulingGroup(schedGroup);
        state.setCurProcState(procState);
        state.setCurRawProcState(procState);
        state.updateLastInvisibleTime(hasVisibleActivities);
        state.setHasForegroundActivities(foregroundActivities);
        state.setCompletedAdjSeq(mAdjSeq);
        state.setCurBoundByNonBgRestrictedApp(boundByNonBgRestricted);

        // if curAdj or curProcState improved, then this process was promoted
        return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState
                || state.getCurCapability() != prevCapability;

4.2 applyOomAdjLSP设置进程所属状态组

computeOomAdjLSP更新完oomadj与procState后通过applyOomAdjLSP来更新冻结情况与设置进程状态组

    /** Applies the computed oomadj, procstate and sched group values and freezes them in set* */
    @GuardedBy({"mService", "mProcLock"})
    private boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now,
            long nowElapsed, @OomAdjReason int oomAdjReson) {
// 省略。。
                switch (curSchedGroup) {
                    case SCHED_GROUP_BACKGROUND:
                        processGroup = THREAD_GROUP_BACKGROUND;
                        break;
                    case SCHED_GROUP_TOP_APP:
                    case SCHED_GROUP_TOP_APP_BOUND:
                        processGroup = THREAD_GROUP_TOP_APP;
                        break;
                    case SCHED_GROUP_RESTRICTED:
                        processGroup = THREAD_GROUP_RESTRICTED;
                        break;
                    default:
                        processGroup = THREAD_GROUP_DEFAULT;
                        break;
                }
                mProcessGroupHandler.sendMessage(mProcessGroupHandler.obtainMessage(
                        0 /* unused */, app.getPid(), processGroup, app.processName));
---分割线
【OomAdjuster-mProcessGroupHandler】
        mProcessGroupHandler = new Handler(adjusterThread.getLooper(), msg -> {
            final int pid = msg.arg1;
            final int group = msg.arg2;
            if (pid == ActivityManagerService.MY_PID) {
                // Skip setting the process group for system_server, keep it as default.
                return true;
            }
            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setProcessGroup "
                        + msg.obj + " to " + group);
            }
            try {
//调用native方法设置进程组
                setProcessGroup(pid, group);
            } catch (Exception e) {
                if (DEBUG_ALL) {
                    Slog.w(TAG, "Failed setting process group of " + pid + " to " + group, e);
                }
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            return true;
        });
---分割线
【Process.java】
    /**
     * Sets the scheduling group for a process and all child threads
     * @hide
     * @param pid The identifier of the process to change.
     * @param group The target group for this process from THREAD_GROUP_*.
     *
     * @throws IllegalArgumentException Throws IllegalArgumentException if
     * <var>tid</var> does not exist.
     * @throws SecurityException Throws SecurityException if your process does
     * not have permission to modify the given thread, or to use the given
     * priority.
     *
     * group == THREAD_GROUP_DEFAULT means to move all non-background priority
     * threads to the foreground scheduling group, but to leave background
     * priority threads alone.  group == THREAD_GROUP_BACKGROUND moves all
     * threads, regardless of priority, to the background scheduling group.
     * group == THREAD_GROUP_FOREGROUND is not allowed.
     *
     * Always sets cpusets.
     */
    @UnsupportedAppUsage
    public static final native void setProcessGroup(int pid, int group)
            throws IllegalArgumentException, SecurityException;

每个进程计算oom时机,计算oom过程,计算oom结果保存,计算结果应用则是几个重点的分析方向。
进程重要性

2.1 Process State

[ActivityManager.java]

import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_RECENT;
import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT;
import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;

2.2 OOM_ADJ

import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ACTIVITY;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ALLOWLIST;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_BACKUP;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_BIND_SERVICE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_COMPONENT_DISABLED;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_EXECUTING_SERVICE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_FINISH_RECEIVER;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_GET_PROVIDER;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_NONE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_PROCESS_BEGIN;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_PROCESS_END;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_REMOVE_PROVIDER;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_REMOVE_TASK;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_RESTRICTION_CHANGE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SHELL;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SHORT_FGS_TIMEOUT;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_RECEIVER;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_SERVICE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_STOP_SERVICE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SYSTEM_INIT;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UID_IDLE;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UI_VISIBILITY;
import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UNBIND_SERVICE;

2.3 Scheduler Group

import static android.os.Process.SCHED_OTHER;
import static android.os.Process.THREAD_GROUP_BACKGROUND;
import static android.os.Process.THREAD_GROUP_DEFAULT;
import static android.os.Process.THREAD_GROUP_RESTRICTED;
import static android.os.Process.THREAD_GROUP_TOP_APP;
import static android.os.Process.THREAD_PRIORITY_DISPLAY;
import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
import static android.os.Process.setProcessGroup;
import static android.os.Process.setThreadPriority;
import static android.os.Process.setThreadScheduler;
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容