美文网首页
Android ActivityManagerService--

Android ActivityManagerService--

作者: DarcyZhou | 来源:发表于2023-11-03 09:40 被阅读0次

    本文转载自:ActivityManagerService之进程管理(四)

    本文基于Android 11.0源码分析

    1.初步了解AMS的进程管理

    1.1 Linux进程调度优先级和调度策略

      调度优先级和调度策略是操作系统中一个很重要的概念。简而言之,它是系统中CPU资源的管理和控制手段。如何理解?此处进行简单介绍。读者可自行阅读操作系统方面的书籍以加深理解。

    • 相对于在OS上运行的应用进程个数来说,CPU的资源非常有限。

    • 调度优先级是OS分配CPU资源给应用进程时(即调度应用进程运行)需要参考的一个指标。一般而言,优先级高的进程将更有机会得到CPU资源。

      调度策略用于描述OS调度模块分配CPU给应用进程所遵循的规则,即当将CPU控制权交给调度模块时,系统如何选择下一个要运行的进程。此处不能仅考虑各进程的调度优先级,因为存在多个进程具有相同调度优先级的情况。在这种情况下,一个需要考虑的重要因素是,每个进程所分配的时间片及它们的使用情况。

      可简单认为,调度优先级及调度策略二者一起影响了系统分配CPU资源给应用进程。注意,此处的措词为“影响”,而非“控制”。因为对于用户空间可以调用的API来说,如果二者能控制CPU资源分配,那么该系统的安全性会大打折扣。

    (1)setpriority

      Linux提供了两个API用于设置调度优先级及调度策略。先来看设置调度优先级的函数setpriority,其原型如下:

    int setpriority(int which, int who, int prio);
    

    其中:

    • which和who参数联合使用。

      • 当which为PRIO_PROGRESS时,who代表一个进程;

      • 当which为PRIO_PGROUP时,who代表一个进程组;

      • 当which为PRIO_USER时,who代表一个uid。

    • 第三个参数prio用于设置应用进程的nicer值,可取范围从-20到19。Linux kernel用nicer值来描述进程的调度优先级,该值越大,表明该进程越优(nice),其被调度运行的几率越低。

    (2)sched_setscheduler

      下面来看设置调度策略的函数sched_setscheduler,其原型如下:

    int sched_setscheduler(pid_t pid, int policy, conststruct sched_param *param);
    

    其中:

    • 第一个参数为进程id。

    • 第二个参数为调度策略。目前Android支持四种调度策略:

      • SCHED_OTHER,标准round-robin分时共享策略(也就是默认的策略);

      • SCHED_BATCH,针对具有batch风格(批处理)进程的调度策略;

      • SCHED_IDLE,针对优先级非常低的适合在后台运行的进程。除此之外,Linux还支持实时(Real-time)调度策略,包括SCHED_FIFO,先入先出调度策略;

      • SCHED_RR,round-robin调度策略,也就是循环调度。这些策略的定义值在Process.java,下面的文章有介绍这个类。

    • param参数中最重要的是该结构体中的sched_priority变量。针对Android中的四种非实时调度策略,该值必须为NULL。

      以上介绍了调度优先级和调度策略的概念。建议读者做个小实验来测试调动优先级及调动策略的作用,步骤如下:

    • 挂载SD卡到PC机并往向其中复制一些媒体文件,然后重新挂载SD卡到手机。该操作就能触发MediaScanner扫描新增的这些媒体文件。

    • 利用top命令查看CPU使用率,会发现进程com.process.media(即MediaScanner所在的进程)占用CPU较高(可达70%以上),原因是该进程会扫描媒体文件,该工作将利用较多的CPU资源。

    • 此时,如果启动另一个进程,然后做一些操作,会发现MediaScanner所在进程的CPU利用率会降下来(例如下降到30%~40%),这表明系统将CPU资源更多地分给了用户正在操作的这个进程。

      出现这种现象的原因是,MediaScannerSerivce的扫描线程将调度优先级设置为11,而默认的调度优先级为0。 相比而言,MediaScannerService优先级真的很高。

    1.2 关于Linux进程oom_adj的介绍

      从Linux kernel 2.6.11开始,内核提供了进程的OOM控制机制,目的是当系统出现内存不足(out of memory,简称OOM)的情况时,Kernel可根据进程的oom_adj来选择并杀死一些进程,以回收内存。简而言之,oom_adj可标示Linux进程内存资源的优先级,其可取范围从-16到15,另外有一个特殊值-17用于禁止系统在OOM情况下杀死该进程。和nicer值一样,oom_adj的值越高,那么在OOM情况下,该进程越有可能被杀掉。每个进程的oom_adj初值为0。

      Linux没有提供单独的API用于设置进程的oom_adj。目前的做法就是向/proc/进程id/oom_adj文件中写入对应的oom_adj值,通过这种方式就能调节进程的oom_adj了。

      另外,有必要简单介绍一下Android为Linux Kernel新增的lowmemorykiller(以后简称LMK)模块的工作方式:LMK的职责是根据当前内存大小去杀死对应oom_adj及以上的进程以回收内存。这里有两个关键参数:为LMK设置不同的内存阈值及oom_adj,它们分别由/sys/module/lowmemorykiller/parameters/minfree和/sys/module/lowmemorykiller/parameters/adj控制。

    (1)注意:这两个参数的典型设置为:

    • minfree:2048,3072,4096,6144,7168,8192 用于描述不同级别的内存阈值,单位为KB。

    • adj:0,1,2,4,7,15 用于描述对应内存阈值的oom_adj值。

      表示当剩余内存为2048KB时,LMK将杀死oom_adj大于等于0的进程。网络上有一些关于Android手机内存优化的方法,其中一种就利用了LMK的工作原理。

    (2)提示
      lowmemorykiller的代码在kernel/drivers/staging/android/lowmemorykiller.c中,感兴趣的读者可尝试自行阅读。

    1.3 关于Android中的进程管理的介绍

      前面介绍了Linux OS中进程管理(包括调度和OOM控制)方面的API,但AMS是如何利用它们的呢?这就涉及AMS中的进程管理规则了。这里简单介绍相关规则。

      Android将应用进程分为五大类,分别为Forground类、Visible类、Service类、Background类及Empty类。这五大类的划分各有规则。

    (1) Forground类
      该类中的进程重要性最高,属于该类的进程包括下面几种情况:

    • 含一个前端Activity(即onResume函数被调用过了,或者说当前正在显示的那个Activity)。

    • 含一个Service,并且该Service和一个前端Activity绑定(例如Music应用包括一个前端界面和一个播放Service,当我们一边听歌一边操作Music界面时,该Service即和一个前端Activity绑定)。

    • 含一个调用了startForground的Service,或者该进程的Service正在调用其生命周期的函数(onCreate、onStart或onDestroy)。

    • 最后一种情况是,该进程中有BroadcastReceiver实例正在执行onReceive函数。

    (2) Visible类
      属于Visible类的进程中没有处于前端的组件,但是用户仍然能看到它们,例如位于一个对话框后的Activity界面。目前该类进程包括两种:

    • 该进程包含一个仅onPause被调用的Activity(即它还在前台,只不过部分界面被遮住)。

    • 或者包含一个Service,并且该Service和一个Visible(或Forground)的Activity绑定(从字面意义上看,这种情况不太好和Forground进程中第二种情况区分)。

    (3) Service类、Background类及Empty类
      这三类进程都没有可见的部分,具体情况如下。

    • Service进程:该类进程包含一个Service。此Service通过startService启动,并且不属于前面两类进程。这种进程一般在后台默默地干活,例如前面介绍的MediaScannerService。

    • Background进程:该类进程包含当前不可见的Activity(即它们的onStop被调用过)。系统保存这些进程到一个LRU(最近最少使用)列表。当系统需要回收内存时,该列表中那些最近最少使用的进程将被杀死。

    • Empty进程:这类进程中不包含任何组件。为什么会出现这种不包括任何组件的进程呢?其实很简单,假设该进程仅创建了一个Activity,它完成工作后主动调用finish函数销毁(destroy)自己,之后该进程就会成为Empty进程。系统保留Empty进程的原因是当又重新需要它们时(例如用户在别的进程中通过startActivity启动了它们),可以省去fork进程、创建Android运行环境等一系列漫长而艰苦的工作。

      通过以上介绍可发现,当某个进程和前端显示有关系时,其重要性相对要高,这或许是体现Google重视用户体验的一个很直接的证据吧。

    2.AMS的进程管理详情

      AMS的进程管理跟三个类密切关系ProcessList,ProcessRecord和Process。方法的话有updateLruProcessLocked、computeOomAdjLocked、updateOomAdjLocked、applyOomAdjLocked 。其实在AMS中保持所有的进程信息:

    //所有的进程信息
    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
    //移除的进程信息
    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
    //用pid来查询相关的进程信息
    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
    

    2.1 ProcessList

    // frameworks/base/services/core/java/com/android/server/am/ProcessList.java
    public final class ProcessList {
        private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
    
        // The minimum time we allow between crashes, for us to consider this
        // application to be bad and stop and its services and reject broadcasts.
        static final int MIN_CRASH_INTERVAL = 60*1000;
    
        // OOM adjustments for processes in various states:
    
        // Uninitialized value for any major or minor adj fields
        static final int INVALID_ADJ = -10000;
    
        // Adjustment used in certain places where we don't know it yet.
        // (Generally this is something that is going to be cached, but we
        // don't know the exact value in the cached range to assign yet.)
        static final int UNKNOWN_ADJ = 1001;
    
        // This is a process only hosting activities that are not visible,
        // so it can be killed without any disruption.
        static final int CACHED_APP_MAX_ADJ = 906;
        static final int CACHED_APP_MIN_ADJ = 900;
    
        // The B list of SERVICE_ADJ -- these are the old and decrepit
        // services that aren't as shiny and interesting as the ones in the A list.
        static final int SERVICE_B_ADJ = 800;
    
        // This is the process of the previous application that the user was in.
        // This process is kept above other things, because it is very common to
        // switch back to the previous app.  This is important both for recent
        // task switch (toggling between the two top recent apps) as well as normal
        // UI flow such as clicking on a URI in the e-mail app to view in the browser,
        // and then pressing back to return to e-mail.
        static final int PREVIOUS_APP_ADJ = 700;
    
        // This is a process holding the home application -- we want to try
        // avoiding killing it, even if it would normally be in the background,
        // because the user interacts with it so much.
        static final int HOME_APP_ADJ = 600;
    
        // This is a process holding an application service -- killing it will not
        // have much of an impact as far as the user is concerned.
        static final int SERVICE_ADJ = 500;
    
        // This is a process with a heavy-weight application.  It is in the
        // background, but we want to try to avoid killing it.  Value set in
        // system/rootdir/init.rc on startup.
        static final int HEAVY_WEIGHT_APP_ADJ = 400;
    
        // This is a process currently hosting a backup operation.  Killing it
        // is not entirely fatal but is generally a bad idea.
        static final int BACKUP_APP_ADJ = 300;
    
        // This is a process only hosting components that are perceptible to the
        // user, and we really want to avoid killing them, but they are not
        // immediately visible. An example is background music playback.
        static final int PERCEPTIBLE_APP_ADJ = 200;
    
        // This is a process only hosting activities that are visible to the
        // user, so we'd prefer they don't disappear.
        static final int VISIBLE_APP_ADJ = 100;
        static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
    
        // This is the process running the current foreground app.  We'd really
        // rather not kill it!
        static final int FOREGROUND_APP_ADJ = 0;
    
        // This is a process that the system or a persistent process has bound to,
        // and indicated it is important.
        static final int PERSISTENT_SERVICE_ADJ = -700;
    
        // This is a system persistent process, such as telephony.  Definitely
        // don't want to kill it, but doing so is not completely fatal.
        static final int PERSISTENT_PROC_ADJ = -800;
    
        // The system process runs at the default adjustment.
        static final int SYSTEM_ADJ = -900;
    
        // Special code for native processes that are not being managed by the system (so
        // don't have an oom adj assigned by the system).
        static final int NATIVE_ADJ = -1000;
    
        // Memory pages are 4K.
        static final int PAGE_SIZE = 4*1024;
    
     private final int[] mOomAdj = new int[] {
                FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
                BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
        };
        // These are the low-end OOM level limits.  This is appropriate for an
        // HVGA or smaller phone with less than 512MB.  Values are in KB.
        private final int[] mOomMinFreeLow = new int[] {
                12288, 18432, 24576,
                36864, 43008, 49152
        };
        // These are the high-end OOM level limits.  This is appropriate for a
        // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
        private final int[] mOomMinFreeHigh = new int[] {
                73728, 92160, 110592,
                129024, 147456, 184320
        };
    

      这个类主要是用于OOM的设定值。什么时候会发生OOM呢?跟oom_adj值有很大关系。oom_adj 的值有几个档位如下:

    AMS16.png

      为了防止剩余内存过低,Android在内核空间有lowmemorykiller(简称LMK),LMK是通过注册shrinker来触发低内存回收的,这个机制并不太优雅,可能会拖慢Shrinkers内存扫描速度,已从内核4.12中移除,后续会采用用户空间的LMKD + memory cgroups机制,这里先不展开LMK讲解。

      进程刚启动时ADJ等于INVALID_ADJ,当执行完attachApplication(),该进程的curAdj和setAdj不相等,则会触发执行setOomAdj()将该进程的节点/proc/pid/oom_score_adj写入oomadj值。下图参数为Android原生阈值,当系统剩余空闲内存低于某阈值(比如147MB),则从ADJ大于或等于相应阈值(比如900)的进程中,选择ADJ值最大的进程,如果存在多个ADJ相同的进程,则选择内存最大的进程。 如下是64位机器,LMK默认阈值图:

    AMS17.png

      在updateOomLevels()过程,会根据手机屏幕尺寸或内存大小来调整scale,默认大多数手机内存都大于700MB,则scale等于1。对于64位手机,阈值会更大些,具体如下。

    // frameworks/base/services/core/java/com/android/server/am/ProcessList.javas
        private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
            // Scale buckets from avail memory: at 300MB we use the lowest values to
            // 700MB or more for the top values.
            float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350);
    
            // Scale buckets from screen size.
            int minSize = 480 * 800;  //  384000
            int maxSize = 1280 * 800; // 1024000  230400 870400  .264
            float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize);
            if (false) {
                Slog.i("XXXXXX", "scaleMem=" + scaleMem);
                Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
                        + " dh=" + displayHeight);
            }
    
            float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
            if (scale < 0) scale = 0;
            else if (scale > 1) scale = 1;
            int minfree_adj = Resources.getSystem().getInteger(
                    com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
            int minfree_abs = Resources.getSystem().getInteger(
                    com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
            if (false) {
                Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
            }
    
            final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
    
            for (int i = 0; i < mOomAdj.length; i++) {
                int low = mOomMinFreeLow[i];
                int high = mOomMinFreeHigh[i];
                if (is64bit) {
                    // Increase the high min-free levels for cached processes for 64-bit
                    if (i == 4) high = (high * 3) / 2;
                    else if (i == 5) high = (high * 7) / 4;
                }
                mOomMinFree[i] = (int)(low + ((high - low) * scale));
            }
    
            if (minfree_abs >= 0) {
                for (int i = 0; i < mOomAdj.length; i++) {
                    mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
                            / mOomMinFree[mOomAdj.length - 1]);
                }
            }
    
            if (minfree_adj != 0) {
                for (int i = 0; i < mOomAdj.length; i++) {
                    mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i]
                            / mOomMinFree[mOomAdj.length - 1]);
                    if (mOomMinFree[i] < 0) {
                        mOomMinFree[i] = 0;
                    }
                }
            }
    
            // The maximum size we will restore a process from cached to background, when under
            // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
            // before killing background processes.
            mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3;
    
            // Ask the kernel to try to keep enough memory free to allocate 3 full
            // screen 32bpp buffers without entering direct reclaim.
            int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
            int reserve_adj = Resources.getSystem().getInteger(
                    com.android.internal.R.integer.config_extraFreeKbytesAdjust);
            int reserve_abs = Resources.getSystem().getInteger(
                    com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
    
            if (reserve_abs >= 0) {
                reserve = reserve_abs;
            }
    
            if (reserve_adj != 0) {
                reserve += reserve_adj;
                if (reserve < 0) {
                    reserve = 0;
                }
            }
    
            if (write) {
                ByteBuffer buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
                buf.putInt(LMK_TARGET);
                for (int i = 0; i < mOomAdj.length; i++) {
                    buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
                    buf.putInt(mOomAdj[i]);
                }
    
                writeLmkd(buf, null);
                SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
                mOomLevelsSet = true;
            }
            // GB: 2048,3072,4096,6144,7168,8192
            // HC: 8192,10240,12288,14336,16384,20480
        }
    

    2.2 ProcessRecord

    // frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
    public final class ProcessRecord {
        private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessRecord" : TAG_AM;
    
        private final BatteryStatsImpl mBatteryStats; // where to collect runtime statistics//管理进程电量统计
        public final ApplicationInfo info; // all about the first app in the process
        final boolean isolated;     // true if this is a special isolated process //独立进程
        public final int uid;       // uid of process; may be different from 'info' if isolated
        final int userId;           // user of process.
        public final String processName;   // name of the process
        // List of packages running in the process
        public final ArrayMap<String, ProcessStats.ProcessStateHolder> pkgList = new ArrayMap<>();
        UidRecord uidRecord;        // overall state of process's uid.
        //进程运行依赖的包
        ArraySet<String> pkgDeps;   // additional packages we have a dependency on
    
        //保存IApplicationThread,通过它可以和应用进程交互
        public IApplicationThread thread;  // the actual proc...  may be null only if
                                    // 'persistent' is true (in which case we
                                    // are in the process of launching the app)
        ProcessState baseProcessTracker;
        BatteryStatsImpl.Uid.Proc curProcBatteryStats;
        public int pid;             // The process of this application; 0 if none
        String procStatFile;        // path to /proc/<pid>/stat
        int[] gids;                 // The gids this process was launched with
        String requiredAbi;         // The ABI this process was launched with
        String instructionSet;      // The instruction set this process was launched with
        boolean starting;           // True if the process is being started
        long lastActivityTime;      // For managing the LRU list//每次updateLruProcessLocked()过程会更新该值
        long lastPssTime;           // Last time we retrieved PSS data
        long nextPssTime;           // Next time we want to request PSS data
        long lastStateTime;         // Last time setProcState changed
        long initialIdlePss;        // Initial memory pss of process for idle maintenance.
        long lastPss;               // Last computed memory pss.
        long lastSwapPss;           // Last computed SwapPss.
        long lastCachedPss;         // Last computed pss when in cached state.
        long lastCachedSwapPss;     // Last computed SwapPss when in cached state.
    
        //和oom_adj有关
        int maxAdj;                 // Maximum OOM adjustment for this process 进程的adj上限(adjustment)
        int curRawAdj;              // Current OOM unlimited adjustment for this process  当前正在计算的adj,这个值有可能大于maxAdj
        int setRawAdj;              // Last set OOM unlimited adjustment for this process 上次计算的curRawAdj设置到lowmemorykiller系统后的adj
        public int curAdj;          // Current OOM adjustment for this process 当前正在计算的adj,这是curRawAdj被maxAdj削平的值
        int setAdj;                 // Last set OOM adjustment for this process 上次计算的curAdj设置到lowmemorykiller系统后的adj
        int verifiedAdj;            // The last adjustment that was verified as actually being set
    
        //和调度优先级有关
        int curSchedGroup;          // Currently desired scheduling class
        int setSchedGroup;          // Last set to background scheduling class
        int vrThreadTid;            // Thread currently set for VR scheduling
    
        //回收内存级别
        //默认是80%,ComponentCallbacks2.TRIM_MEMORY_COMPLETE
        int trimMemoryLevel;        // Last selected memory trimming level
    
        //判断该进程的状态,主要和其中运行的Activity,Service有关  ActivityManager.PROCESS_STATE
    
        public int curProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state
        int repProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state
        int setProcState = PROCESS_STATE_NONEXISTENT; // Last set process state in process tracker
        int pssProcState = PROCESS_STATE_NONEXISTENT; // Currently requesting pss for
        int savedPriority;          // Previous priority value if we're switching to non-SCHED_OTHER
        int renderThreadTid;        // TID for RenderThread
        boolean serviceb;           // Process currently is on the service B list
        boolean serviceHighRam;     // We are forcing to service B list due to its RAM use
        boolean notCachedSinceIdle; // Has this process not been in a cached state since last idle?
        boolean hasClientActivities;  // Are there any client services with activities?
        boolean hasStartedServices; // Are there any started services running in this process?
        boolean foregroundServices; // Running any services that are foreground?
        boolean foregroundActivities; // Running any activities that are foreground?
        boolean repForegroundActivities; // Last reported foreground activities.
       //这个表示进程是否绑定的activity,通过activities.size的值和visible来判断,如果visible=true,就是false
        boolean systemNoUi;         // This is a system process, but not currently showing UI.
        boolean hasShownUi;         // Has UI been shown in this process since it was started?
        //显示顶层的ui
        boolean hasTopUi;           // Is this process currently showing a non-activity UI that the user
                                    // is interacting with? E.g. The status bar when it is expanded, but
                                    // not when it is minimized. When true the
                                    // process will be set to use the ProcessList#SCHED_GROUP_TOP_APP
                                    // scheduling group to boost performance.
        boolean hasOverlayUi;       // Is the process currently showing a non-activity UI that
                                    // overlays on-top of activity UIs on screen. E.g. display a window
                                    // of type
                                    // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
                                    // When true the process will oom adj score will be set to
                                    // ProcessList#PERCEPTIBLE_APP_ADJ at minimum to reduce the chance
                                    // of the process getting killed.
        boolean pendingUiClean;     // Want to clean up resources from showing UI?
        boolean hasAboveClient;     // Bound using BIND_ABOVE_CLIENT, so want to be lower
        boolean treatLikeActivity;  // Bound using BIND_TREAT_LIKE_ACTIVITY
    
        //判断该进程的状态,主要和其中运行的Activity,Service有关
        boolean bad;                // True if disabled in the bad process list  是否处于系统BadProcess列表
        public boolean killedByAm;  // True when proc has been killed by activity manager, not for RAM//当值为true,意味着该进程是被AMS所杀,而非由于内存低而被LMK所杀
        public boolean killed;      // True once we know the process has been killed//进程被杀死
        boolean procStateChanged;   // Keep track of whether we changed 'setAdj'.
        boolean reportedInteraction;// Whether we have told usage stats about it being an interaction
        boolean unlocked;           // True when proc was started in user unlocked state
        long interactionEventTime;  // The time we sent the last interaction event
        long fgInteractionTime;     // When we became foreground for interaction purposes
        public String waitingToKill; // Process is waiting to be killed when in the bg, and reason
        Object forcingToImportant;  // Token that is forcing this process to be important
    
        //序号,每次调节进程优先级或者LRU列表位置时,这些序号都会递增
        int adjSeq;                 // Sequence id for identifying oom_adj assignment cycles
        int lruSeq;                 // Sequence id for identifying LRU update cycles
        CompatibilityInfo compat;   // last used compatibility mode
        IBinder.DeathRecipient deathRecipient; // Who is watching for the death.
        //activity正在运行
        ActiveInstrumentation instr;// Set to currently active instrumentation running in process
        boolean usingWrapper;       // Set to true when process was launched with a wrapper attached
        final ArraySet<BroadcastRecord> curReceivers = new ArraySet<BroadcastRecord>();// receivers currently running in the app
        long whenUnimportant;       // When (uptime) the process last became unimportant
        long lastCpuTime;           // How long proc has run CPU at last check
        long curCpuTime;            // How long proc has run CPU most recently
        long lastRequestedGc;       // When we last asked the app to do a gc
        long lastLowMemory;         // When we last told the app that memory is low
        long lastProviderTime;      // The last time someone else was using a provider in this process.
        boolean reportLowMemory;    // Set to true when waiting to report low mem
        boolean empty;              // Is this an empty background process?
        boolean cached;             // Is this a cached process?
        String adjType;             // Debugging: primary thing impacting oom_adj.
        int adjTypeCode;            // Debugging: adj code to report to app.
        Object adjSource;           // Debugging: option dependent object.
        int adjSourceProcState;     // Debugging: proc state of adjSource's process.
        Object adjTarget;           // Debugging: target component impacting oom_adj.
        Runnable crashHandler;      // Optional local handler to be invoked in the process crash.
    
        // all activities running in the process
        final ArrayList<ActivityRecord> activities = new ArrayList<>();
        // all ServiceRecord running in this process
        final ArraySet<ServiceRecord> services = new ArraySet<>();
        // services that are currently executing code (need to remain foreground).
        final ArraySet<ServiceRecord> executingServices = new ArraySet<>();
        // All ConnectionRecord this process holds
        final ArraySet<ConnectionRecord> connections = new ArraySet<>();
        // all IIntentReceivers that are registered from this process.
        final ArraySet<ReceiverList> receivers = new ArraySet<>();
        // class (String) -> ContentProviderRecord
        //保持provider
        final ArrayMap<String, ContentProviderRecord> pubProviders = new ArrayMap<>();
        // All ContentProviderRecord process is using
        final ArrayList<ContentProviderConnection> conProviders = new ArrayList<>();
        //有相关的class运行在这个进程中
        String isolatedEntryPoint;  // Class to run on start if this is a special isolated process.
        String[] isolatedEntryPointArgs; // Arguments to pass to isolatedEntryPoint's main().
    
        boolean execServicesFg;     // do we need to be executing services in the foreground?
        boolean persistent;         // always keep this application running?//经常不被杀死,杀死也会被系统重新启动
        boolean crashing;           // are we in the process of crashing?
        Dialog crashDialog;         // dialog being displayed due to crash.
        boolean forceCrashReport;   // suppress normal auto-dismiss of crash dialog & report UI?
        boolean notResponding;      // does the app have a not responding dialog?
        Dialog anrDialog;           // dialog being displayed due to app not resp.
        boolean removed;            // has app package been removed from device?
        boolean debugging;          // was app launched for debugging?
        boolean waitedForDebugger;  // has process show wait for debugger dialog?
        Dialog waitDialog;          // current wait for debugger dialog
    
        String shortStringName;     // caching of toShortString() result.
        String stringName;          // caching of toString() result
    

    ProcessRecord 记录了进程的所有信息,比如进程名,进程包的activity ,service以及oom的阈值等有关进程的信息,具体可以看上面的代码块,有关此类的介绍可以看这篇博文:https://blog.csdn.net/tonyandroid1984/article/details/70224827

    2.3 Process

    // frameworks/base/core/java/android/os/Process.java
     public static final int THREAD_PRIORITY_DEFAULT = 0;
    
        /*
         * ***************************************
         * ** Keep in sync with utils/threads.h **
         * ***************************************
         */
    
        /**
         * Lowest available thread priority.  Only for those who really, really
         * don't want to run if anything else is happening.
         * Use with {@link #setThreadPriority(int)} and
         * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
         * {@link java.lang.Thread} class.
         */
        public static final int THREAD_PRIORITY_LOWEST = 19;
    
        /**
         * Standard priority background threads.  This gives your thread a slightly
         * lower than normal priority, so that it will have less chance of impacting
         * the responsiveness of the user interface.
         * Use with {@link #setThreadPriority(int)} and
         * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
         * {@link java.lang.Thread} class.
         */
        public static final int THREAD_PRIORITY_BACKGROUND = 10;
    
        /**
         * Standard priority of threads that are currently running a user interface
         * that the user is interacting with.  Applications can not normally
         * change to this priority; the system will automatically adjust your
         * application threads as the user moves through the UI.
         * Use with {@link #setThreadPriority(int)} and
         * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
         * {@link java.lang.Thread} class.
         */
        public static final int THREAD_PRIORITY_FOREGROUND = -2;
    
        /**
         * Standard priority of system display threads, involved in updating
         * the user interface.  Applications can not
         * normally change to this priority.
         * Use with {@link #setThreadPriority(int)} and
         * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
         * {@link java.lang.Thread} class.
         */
        public static final int THREAD_PRIORITY_DISPLAY = -4;
    
        /**
         * Standard priority of the most important display threads, for compositing
         * the screen and retrieving input events.  Applications can not normally
         * change to this priority.
         * Use with {@link #setThreadPriority(int)} and
         * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
         * {@link java.lang.Thread} class.
         */
        public static final int THREAD_PRIORITY_URGENT_DISPLAY = -8;
    
        /**
         * Standard priority of audio threads.  Applications can not normally
         * change to this priority.
         * Use with {@link #setThreadPriority(int)} and
         * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
         * {@link java.lang.Thread} class.
         */
        public static final int THREAD_PRIORITY_AUDIO = -16;
    
        /**
         * Standard priority of the most important audio threads.
         * Applications can not normally change to this priority.
         * Use with {@link #setThreadPriority(int)} and
         * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
         * {@link java.lang.Thread} class.
         */
        public static final int THREAD_PRIORITY_URGENT_AUDIO = -19;
    
        /**
         * Minimum increment to make a priority more favorable.
         */
        public static final int THREAD_PRIORITY_MORE_FAVORABLE = -1;
    
        /**
         * Minimum increment to make a priority less favorable.
         */
        public static final int THREAD_PRIORITY_LESS_FAVORABLE = +1;
    
        /**
         * Default scheduling policy
         * @hide
         */
        //以下就是进程创建的调度策略
        public static final int SCHED_OTHER = 0;
    
        /**
         * First-In First-Out scheduling policy
         * @hide
         */
        public static final int SCHED_FIFO = 1;
    
        /**
         * Round-Robin scheduling policy
         * @hide
         */
        public static final int SCHED_RR = 2;
    
        /**
         * Batch scheduling policy
         * @hide
         */
        public static final int SCHED_BATCH = 3;
    
        /**
         * Idle scheduling policy
         * @hide
         */
        public static final int SCHED_IDLE = 5;
    
        //paid,tid 的获取
        public static final int myPid() {
            return Os.getpid();
        }
    
        /**
         * Returns the identifier of this process' parent.
         * @hide
         */
        public static final int myPpid() {
            return Os.getppid();
        }
    
        /**
         * Returns the identifier of the calling thread, which be used with
         * {@link #setThreadPriority(int, int)}.
         */
        public static final int myTid() {
            return Os.gettid();
        }
    
        /**
         * Returns the identifier of this process's uid.  This is the kernel uid
         * that the process is running under, which is the identity of its
         * app-specific sandbox.  It is different from {@link #myUserHandle} in that
         * a uid identifies a specific app sandbox in a specific user.
         */
        public static final int myUid() {
            return Os.getuid();
        }
    
      //设置线程等级,也就是更大的可能获得cpu调度的时间。
        public static final native void setThreadPriority(int tid, int priority)
                throws IllegalArgumentException, SecurityException;
    
        public static final native void setThreadPriority(int priority)
                throws IllegalArgumentException, SecurityException;
    
        //设置线程的调度等级和策略,等级有-20到19  策略有SCHED_OTHER,SCHED_FIFO,SCHED_RR
        public static final native void setThreadScheduler(int tid, int policy, int priority)
                throws IllegalArgumentException;
    
        //group == THREAD_GROUP_FOREGROUND
        public static final native void setProcessGroup(int pid, int group)
                throws IllegalArgumentException, SecurityException;
    
        /**
         * Return the scheduling group of requested process.
         *
         * @hide
         */
        public static final native int getProcessGroup(int pid)
                throws IllegalArgumentException, SecurityException;
    

    以上的是代码块并没有包含全部的类信息,只是挑选一些比较重要的字段和函数来说明。

    相关文章

      网友评论

          本文标题:Android ActivityManagerService--

          本文链接:https://www.haomeiwen.com/subject/femvvdtx.html