2024年Android Freezer_cachedappoptimizer,2024年最新HarmonyOS鸿蒙架构 ...

金歌  金牌会员 | 2024-9-27 00:03:35 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 861|帖子 861|积分 2583

深知大多数程序员,想要提拔技能,通常是本身探索发展,但本身不成体系的自学结果低效又漫长,而且极易遇到天花板技术故步自封!



既有恰当小白学习的零基础资料,也有恰当3年以上履历的小搭档深入学习提拔的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比力多,这里只是将部门目次截图出来,全套包罗大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
必要这份体系化的资料的朋侪,可以戳这里获取
Android Q 开始,谷歌引入了cgroup抽象层,搭配使用任务设置文件,来屏蔽底层cgroup调用细节,向上提供API。cgroup抽象层编译成库libprocessgroup。抽象层通过往cgroup的文件节点写入相应的值,来触发kernel的回调。
终极kernel cgroup机制的freezer控制子体系真正实现了冰冻进程的功能。
一个进程从前台运行到被冰冻的路程

2 Framework 上层

2.1 代码路径及流程

  1. frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java
  2. frameworks/base/services/core/java/com/android/server/am/CachedAppOptimizer.java
  3. frameworks/base/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp
  4. frameworks/base/core/java/android/os/Process.java
  5. frameworks/base/core/jni/android_util_Process.cpp
复制代码
2.2 OomAdjuster更新进程adj的场景

  1. static final String OOM_ADJ_REASON_NONE = OOM_ADJ_REASON_METHOD + "_meh";
  2. static final String OOM_ADJ_REASON_ACTIVITY = OOM_ADJ_REASON_METHOD + "_activityChange";
  3. static final String OOM_ADJ_REASON_FINISH_RECEIVER = OOM_ADJ_REASON_METHOD + "_finishReceiver";
  4. static final String OOM_ADJ_REASON_START_RECEIVER = OOM_ADJ_REASON_METHOD + "_startReceiver";
  5. static final String OOM_ADJ_REASON_BIND_SERVICE = OOM_ADJ_REASON_METHOD + "_bindService";
  6. static final String OOM_ADJ_REASON_UNBIND_SERVICE = OOM_ADJ_REASON_METHOD + "_unbindService";
  7. static final String OOM_ADJ_REASON_START_SERVICE = OOM_ADJ_REASON_METHOD + "_startService";
  8. static final String OOM_ADJ_REASON_GET_PROVIDER = OOM_ADJ_REASON_METHOD + "_getProvider";
  9. static final String OOM_ADJ_REASON_REMOVE_PROVIDER = OOM_ADJ_REASON_METHOD + "_removeProvider";
  10. static final String OOM_ADJ_REASON_UI_VISIBILITY = OOM_ADJ_REASON_METHOD + "_uiVisibility";
  11. static final String OOM_ADJ_REASON_ALLOWLIST = OOM_ADJ_REASON_METHOD + "_allowlistChange";
  12. static final String OOM_ADJ_REASON_PROCESS_BEGIN = OOM_ADJ_REASON_METHOD + "_processBegin";
  13. static final String OOM_ADJ_REASON_PROCESS_END = OOM_ADJ_REASON_METHOD + "_processEnd";
复制代码
通过更新原因可以看到,进程的状态变化,或者组件的状态变化会触发重新计算adj。
举例, 当一个APP处置惩罚广播时,就会触发重新计算这个APP的adj,此时的更新原因是OOM_ADJ_REASON_START_RECEIVER:
  1. private final void processCurBroadcastLocked(BroadcastRecord r,
  2.               ProcessRecord app) throws RemoteException {
  3.           ......
  4.           r.receiver = thread.asBinder();
  5.           r.curApp = app;
  6.           final ProcessReceiverRecord prr = app.mReceivers;
  7.           prr.addCurReceiver(r);
  8.           app.mState.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
  9.           mService.updateLruProcessLocked(app, false, null);
  10.           // Make sure the oom adj score is updated before delivering the broadcast.
  11.           // Force an update, even if there are other pending requests, overall it still saves time,
  12.           // because time(updateOomAdj(N apps)) <= N * time(updateOomAdj(1 app)).
  13.           mService.enqueueOomAdjTargetLocked(app);
  14.           mService.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_RECEIVER);
  15.           ......
  16.       }
复制代码
OomAdjuster在computeOomAdjLSP中会将该app的adj提拔至FOREGROUND_APP_ADJ:
  1. private boolean computeOomAdjLSP(ProcessRecord app, int cachedAdj,
  2.               ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,
  3.               boolean computeClients) {
  4.               ......
  5.           } else if (state.getCachedIsReceivingBroadcast(mTmpBroadcastQueue)) {
  6.               // An app that is currently receiving a broadcast also
  7.               // counts as being in the foreground for OOM killer purposes.
  8.               // It's placed in a sched group based on the nature of the
  9.               // broadcast as reflected by which queue it's active in.
  10.               adj = ProcessList.FOREGROUND_APP_ADJ;
  11.               schedGroup = (mTmpBroadcastQueue.contains(mService.mFgBroadcastQueue))
  12.                       ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
  13.               state.setAdjType("broadcast");
  14.               procState = ActivityManager.PROCESS_STATE_RECEIVER;
  15.               if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
  16.                   reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app);
  17.               }
  18.           }
  19.           ......
复制代码
2.3 Debounce time

当某个APP进程的adj达到CACHED_APP_MIN_ADJ时,CachedAppOptimizer就会调用freezeAppAsyncLSP,在debounce time之后,正式冰冻该进程, 这是为了防止进程在进入cached状态时另有任务没有完成从而间接影响用户体验。
Debounce time 在Android S 上默认是十分钟,这个值是可以在线修改的, 好比改为1秒:
  1. adb shell device_config put activity_manager_native_boot freeze_debounce_timeout 1000
复制代码
修改后的值重启会失效,变回默认值。
与异步冰冻流程相反,解冻的过程是同步举行的,一个App进程一旦被解冻成功,它就立刻恢复正常运行。
2.4 freezeProcess


第一步,检查文件锁"/proc/locks"的状态。这是为了防止冰冻进程持有文件锁引起死锁。思量到一些特殊场景下,进程在被冰冻的过程中拿住了文件锁,冰冻成功后还会再检查一次,发现持有锁就立刻解冻。
第二步,freeze binder。这一步禁掉该进程对同步binder请求的接收和处置惩罚,以及对异步binder请求的处置惩罚。该过程必要在100ms内成功,如果进程必要处置惩罚的请求过多导致无法完成,则再多给一轮debounce time。
第三步,setProcessFrozen,调用抽象层提供的API冰冻进程。
第四步,再次检查该进程有没有必要处置惩罚的binder请求,有则解冻进程,再多给一轮debounce time。这个检查是为一些特殊场景下,进程在被冰冻的过程中产生了binder请求。
2.5 setProcessFrozen

  1. void android_os_Process_setProcessFrozen( JNIEnv *env, jobject clazz, jint pid, jint uid, jboolean freeze)
  2.   {
  3.       bool success = true;
  4.   
  5.       if (freeze) {
  6.           success = SetProcessProfiles(uid, pid, {"Frozen"});
  7.       } else {
  8.           success = SetProcessProfiles(uid, pid, {"Unfrozen"});
  9.       }
  10.   
  11.       if (!success) {
  12.           signalExceptionForGroupError(env, EINVAL, pid);
复制代码
调用cgroup抽象层的SetProcessProfiles, 传入参数“Frozen”。
3 cgroup 中间抽象层

cgroup中间抽象层libprocessgroup,重要提供两个功能,其一在启动阶段,根据cgroups.json 来装载具体的cgroup; 其二根据task_profiles.json来界说对cgroup具体的操作以及参数。 重要代码:
  1. /system/core/libprocessgroup/
复制代码
3.1 cgroups.json

示例文件:
  1. {
  2.   "Cgroups": [
  3.     {
  4.       "Controller": "cpu",
  5.       "Path": "/dev/cpuctl",
  6.       "Mode": "0755",
  7.       "UID": "system",
  8.       "GID": "system"
  9.     },
  10.     {
  11.       "Controller": "memory",
  12.       "Path": "/dev/memcg",
  13.       "Mode": "0700",
  14.       "Optional": true
  15.     }
  16.   ],
  17. "Cgroups2": {
  18.    "Path": "/sys/fs/cgroup",
  19.    "Mode": "0755",
  20.    "UID": "system",
  21.    "GID": "system",
  22.    "Controllers": [
  23.      {
  24.        "Controller": "freezer",
  25.        "Path": ".",
  26.        "Mode": "0755",
  27.        "UID": "system",
  28.        "GID": "system"
  29.      }
  30.    ]
  31. }
  32. }
复制代码
该文件分为两部门,“Cgroups” 描述cgroup v1 的控制子体系 和"Cgroups2" 描述cgroup v2的控制子体系。如果不了解cgroup 两个版本,可以参看以下网址:
www.kernel.org/doc/html/la… www.kernel.org/doc/html/la…
目前v1和v2是共存的, freezer所使用的是v2,对应根目次是/sys/fs/cgroup, UID和GID都是system。
启动阶段,Init在SetupCgroupAction中通过调用CgroupSetup,剖析cgroups.json文件,完成对cgroup的装载。
必要留意的是,cgroups.json文件大概不止一个:
  1. /system/core/libprocessgroup/profiles/cgroups.json              //默认文件,都有
  2. /system/core/libprocessgroup/profiles/cgroups_<API level>.json  //API级别的文件,可能有
  3. /vendor/xxx/cgroups.json                                        //vendor自定义的文件
复制代码
这三个文件加载的顺序是: 默认–> API级别 --> vendor,于是就存在一个覆盖的流程。只要后面一个文件中界说的"Controller"与前面的字符串雷同,就会覆盖前者的界说。
形成的层级布局是这样的:

Android freezer 在/sys/fs/cgroup下创建了以uid/pid命名的二级子目次,对uid节点的控制会同步应用于其下面所有的pid节点。 uid在应用安装的时间确定, pid在应用使用的时间产生。如果manifest中使用了android:process,则在当前uid目次下创建一个新的pid开头的目次; 如果进程自动调用了fork产生子进程,则不会产生新的pid目次,而是放在父进程目次下,这就意味着父进程被冰冻的时间同目次的子进程也会被冰冻。
3.2 task_profiles.json

示例 task_profiles.json
  1. {
  2.   "Attributes": [
  3.      {
  4.        "Name": "UClampLatencySensitive",
  5.        "Controller": "cpu",
  6.        "File": "cpu.uclamp.latency_sensitive"
  7.      },
  8.      {
  9.        "Name": "FreezerState",
  10.        "Controller": "freezer",
  11.        "File": "cgroup.freeze"
  12.      }
  13.    ],
  14.    "Profiles": [
  15.      {
  16.        "Name": "Frozen",
  17.        "Actions": [
  18.          {
  19.            "Name": "SetAttribute",
  20.            "Params":
  21.            {
  22.              "Name": "FreezerState",
  23.              "Value": "1"
  24.            }
  25.          }
  26.        ]
  27.      },
  28.      {
  29.        "Name": "Unfrozen",
  30.        "Actions": [
  31.          {
  32.            "Name": "SetAttribute",
  33.            "Params":
  34.            {
  35.              "Name": "FreezerState",
  36.              "Value": "0"
  37.            }
  38.          }
  39.        ]
  40.      },
  41.     {
  42.        "Name": "CpuPolicySpread",
  43.        "Actions": [
  44.          {
  45.            "Name": "SetAttribute",
  46.            "Params":
  47.            {
  48.              "Name": "UClampLatencySensitive",
  49.              "Value": "1"
  50.            }
  51.          }
  52.        ]
  53.      }
  54.    ],
  55.    "AggregateProfiles": [
  56.      {
  57.        "Name": "SCHED_SP_BACKGROUND",
  58.        "Profiles": [ "HighEnergySaving", "LowIoPriority", "TimerSlackHigh" ]
  59.      }
  60.    ]
  61. **深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
  62. ![](https://i-blog.csdnimg.cn/blog_migrate/1e210328c1ebf43f08d3b6c5f5c13b48.png)
  63. ![img](https://img-blog.csdnimg.cn/img_convert/b81c01078cc47958a8165730f909b09e.png)
  64. ![img](https://img-blog.csdnimg.cn/img_convert/8720b3d6a632247f2492e850d3daa982.png)
  65. **既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!**
  66. **由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
  67. **[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**
  68. sdnimg.cn/direct/743b668910224b259a5ffe804fa6d0db.png)
  69. [外链图片转存中...(img-QEF5yALi-1715607349654)]
  70. [外链图片转存中...(img-sxCQ4f3f-1715607349655)]
  71. **既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!**
  72. **由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
  73. **[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

金歌

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表