关于杀后台

查看 225|回复 19
作者:海浪逃向岛屿   

你是否遇到过一觉醒来, 最近任务被扫荡一通的痛苦. 即使你给所有应用都上了锁, 给了自启动权限, 捣鼓设置里面的种种开关, 却依旧逃不过系统的杀戮. 起初, 我把手机从8G升级到了12G内存. 那时, 我天真地认为, 只要内存够大, 就能喂饱安卓这头饥饿的内存老虎, 就能让其停止对APP后台的猎杀. 可结果是, 即使后台内存占用不到一半, 也没能活过一个下午, 甚至连简单的切出微信回消息再切回来这短短的10秒时间, 都有可能被杀后台. 究竟是什么魔力在驱使着Android系统如此激进的杀死后台.
好吧, 关于杀后台这事, 确实没那么简单, 但也没那么复杂. 在GitHub上就能找到一篇去年发表的文章Phantom, Cached And Empty Processes
里面介绍了Android 12引入的后台进程管理新特性Phantom Process, 姑且暂称它为虚进程吧. 什么是虚进程? 文章是这样解释的:
It's any process that has been forked from the main app process and is now either a child of the app process or of init process.
APP主进程或初始化进程的所有子进程均视为虚进程, 虚进程将受到非常严格的限制与管控. 具体体现为, 当虚进程使用的CPU时间超过一定阈值时, 就会触发系统的"清算时刻", 清算时刻不仅会把犯事的虚进程杀死, 还会"株连九族", 将其所有兄弟进程及其父进程通通宰掉. 鉴于国内APP普遍的"野蛮"行为, 让其在后台待一晚上还能不搞事的几乎不存在.
此外, 当系统虚进程总体数量超过一定阈值时(默认是32个), 也会触发"清算时刻", 此时将按照oom adj(一个进程保活优先级参数)的顺序逐个"清算", 直到虚进程的数量达到阈值以下.
看到这里, 你可能会问, Android 12引入的这个新特性如此激进, 就没有相应的选项来开启或关闭吗? 有, 文章中也给出了答案, 只要使用adb/root权限执行命令"settings put global settings_enable_monitor_phantom_procs false", 即可停用虚进程相关的监控行为, 但仅限Android 12L与Android 13.
别急, Android 12也不是完全没有操作空间, 使用adb/root权限执行命令"/system/bin/device_config put activity_manager max_phantom_processes 114514"即可将虚进程数量阈值提高到114514个. 能一定程度上减缓系统的杀后台行为.
然而这并不能算是一种解决方案, 至少对于我个人来说, 不然我甜美换成12G内存手机是拿来供着这Android的吗? 要我来说, 这Android 12引入的虚进程新特性真就是一托, 让APP卡片上的那个锁完全变成了一个摆设, 就跟MIUI甜美那屏幕刷新率设置一样, 120Hz打开输入法, 导航, 网易云就变成60Hz, 用户完全没有选择权, 小米13上的APP自定义刷新率甚至还能拿来在发布会上吹, 脸都不要了.
扯远了咳咳, 虽然Android 12不能通过执行命令的方式完全禁用这个新特性, 但并不代表Android 13就能通过一行简单的命令就能一劳永逸, 首先是文章中提到的同步问题, 开启设备同步会导致你的设置每隔一段时间就会被系统重置, 而禁用同步则面临系统无法从崩溃中恢复的风险.
而最重要的是, 禁用新特性并不能完全阻止系统的杀后台行为. 是的, 即使你完全禁用了新特性, 一觉醒来后依旧有可能看到你的APP在最近任务里面消失不见, 也就是俗称的掉卡片. 实际上, 除了文章中提到的Phantom Process机制. Android还有另一套机制管理着后台应用, 那便是Recent Tasks(最近任务), 也就是我们上划应用时所看到的APP卡片.
任务分为可见任务与不可见任务, 可见任务有一个可见范围, 可见范围由设备类型, 上次任务的活动时间或其他任务状态决定, 不在可见范围的任务将会被trim(剪掉, 也就是清理的意思). 那怎么判断一个应用是否在可见范围内呢
可以知道, 在mMinNumVisibleTasks与mMaxNumVisibleTasks范围之间的最近任务是可见的, 并且拥有固定模式的子任务的最近任务也将保留, 最后, 如果一个任务的不活跃时间超过一定阈值, 那它将被排除在可见范围外. 这也是为什么最近任务长时间不打开会被清理的原因.
在MIUI系统上, 除了Android底层的杀后台机制, MIUI自己也有相应的杀后台机制, 酷安已有很多大佬分析了, 简单来说就是反编译电量与性能, 可以发现在里面也有相应的杀死不活跃后台机制(似乎可以在设置里关闭), 我就不赘述了.
至此, 我们已经发现了三处引起系统杀后台的元凶:
1.Android 12引入的新特性Phantom Process;
2.Android的Recent Tasks管理机制;
3.MIUI功耗管理工具电量与性能(PowerKeeper)的杀后台行为.
如何解决:
1.Phantom Process
虚进程特性杀后台主要依据是CPU使用时间与最大进程数, 是否过量CPU时间由函数checkExcessivePowerUsageLPr决定, hook使之返回false即可.
超出最大进程数会由函数trimPhantomProcessesIfNecessary执行清算动作, hook使之置空即可.
2.Recent Tasks
最近任务是否可见由isInVisibleRange函数决定, 为避免最近任务数量过多或非活动时间超出阈值而导致杀后台, 将函数第三个参数numVisibleTasks(当前可见任务数量)置为0即可.
3.电量与性能
这个最简单, 将三个杀后台函数置空即可.
至此, 大概能总结出Android为何如此激进也限制后台运行了.
其中一个因素就是"省电". 从Android 12的新特性Phantom Process里可以看出, Android会严格限制进程使用CPU时间, 只要超过一定阈值, 就会直接杀死对应进程与APP.
另一个因素, 应该是"资源有限". 这里的资源指的是各种CPU, 内存等资源, 当然也有部分历史因素, 对于目前动辄8G12G起步的手机来说, "资源有限"在Android里的定义显然需要随时代进行更新了.
还有一个因素, 我想可能是"省心"吧. Android系统作为移动设备最常见的系统之一, 而移动设备又是目前人们日常生活中最常用的设备之一. 由Android来帮助人们完成不活跃APP的回收工作, 出于"省心"的初衷来看, 是没啥毛病的. 同为最常见操作系统之一的Windows, 它的后台程序却更加"自由", 但很多时候却都需要用户手动关闭. 只可惜硬件资源是有限的, "省心"与"自由"之间必定会存在难以调和的矛盾. 对于我个人而言, 我更倾向于"自由".
至此, 系统杀后台的问题得以缓解, 但这并不代表你就可以狂开后台榨干系统的每一滴内存, 上面所讨论的只是系统以"省电"与"省心"为目的的杀后台行为, 而系统杀后台的另一主要因素"内存占用", 依旧有不少的操作空间, 此乃后话.
----------------
3月20日补充
之前关于防杀后台的内容其实还没说完, 今天终于有时间补充. GitHub那篇文章其实还提到一点, 就是已缓存应用Cached Processes数量过多(单纯指数量而不是占用)也有可能被系统kill掉. 系统默认最大缓存进程数CUR_MAX_CACHED_PROCESSES是32, 而且实际上系统杀后台的阈值比这个值还要低, 因为这个最大缓存进程数是包括空进程的, 而最大空进程数量CUR_MAX_EMPTY_PROCESSES是16.
至于为什么是这个值, 文章指出, 这个值从2010年(大概安卓2.2时代)起就一直是32, 在当时还是只有512MB/1G内存的设备来说32或许是一个比较合理的数值, 然而对于今天动辄8G内存起步的安卓设备来说显然过于保守了.
因此, 可以在系统启动时将CUR_MAX_CACHED_PROCESSES设置为Integer.MAX_VALUE来避免因已缓存应用数量过多而导致杀后台事件发生.
此外, 文章还提到一个值CUR_TRIM_CACHED_PROCESSES, 文章认为这是系统杀进程的下限阈值, 其实不然, CUR_TRIM_CACHED_PROCESSES主要用来判断触发LMK(低内存回收)机制时系统内存的紧张程度
与本文所描述的杀后台情景(指系统出于省电目的而发生的杀后台事件)无关.
总结:
一.如果你有root权限, 请安装Xposed模块Don't Kill
二.如果你没有root权限, 只能尽可能地防止系统杀后台事件发生, 请使用adb权限执行以下命令:
第一步, 首先要禁止系统对device_config配置进行更新, 防止已生效的参数被系统覆盖(Android 10以下的无需这个操作, 请跳到第二步), 有两种方法:
1.永久禁止更新(使用此方法时只需要执行一次第二步的命令)
adb shell "/system/bin/device_config set_sync_disabled_for_tests persistent";
2.下一次开机/重启前禁止更新(使用此方法时需要每次开机都执行第二步的命令)
adb shell "/system/bin/device_config set_sync_disabled_for_tests until_reboot";
注意, 禁止系统更新device_config配置是有风险的, 这意味着系统有可能无法从崩溃中恢复.
如何恢复系统自动更新device_config配置
adb shell "/system/bin/device_config set_sync_disabled_for_tests none";
第二步, 禁止系统更新device_config配置后, 执行以下命令:
如果你是Android 12L/13及以上:
adb shell "settings put global settings_enable_monitor_phantom_procs false";
adb shell "/system/bin/device_config put activity_manager max_cached_processes 2147483647";
如果你是Android 12:
adb shell "/system/bin/device_config put activity_manager max_phantom_processes 2147483647";
adb shell "/system/bin/device_config put activity_manager max_cached_processes 2147483647";
注意, 由于Android 12无法通过adb命令关闭Phantom Process机制, 以上命令只能有限的阻止Phantom Process机制杀后台.
如果你是Android 10/11:
adb shell "/system/bin/device_config put activity_manager max_cached_processes 2147483647";
如果你是Android 8/9, 那你不需要执行第一步, 你需要先执行
adb shell "settings get global activity_manager_constants";
来获取一个字符串(里面是关于一堆全局变量的描述), 然后你需要在这个字符串的末尾加上",max_cached_processes=2147483647", 这样你就可以得到一个拼接过的字符串, 然后再执行命令
adb shell "settings put global activity_manager_constants ";
   









后台, 进程, 系统

愿你爱我无期   
需要刷入模块吗 为什么没有桌面快捷应用
很好色的小学生   
禁止更新是系统那个更新?
两种方法,第2种才会无法从崩溃中回复?第1不会?
希望有大佬说明一下
律化娜QAQ   
鹿忆往昔人   
大佬牛B[嘿哈][嘿哈][嘿哈][嘿哈]
宛如少女的猫   
miui14提示inaccessible or not found[受虐滑稽]
意气风发的   
试试这个,最后的希望了
自由的巴巴托斯   
和noactive防止杀后台插件功能有部分冲突吗?
海浪逃向岛屿
OP
  
效果立竿见影,太强了大佬![惊讶]
小碍同学   
根据此文章而作的防杀后台模块https://www.coolapk.com/feed/43786627?shareKey=MWM1OGQyNTQyNTI5NjNmZjY4MjU~&shareUid=1755624&shareFrom=com.coolapk.market_13.0.1
您需要登录后才可以回帖 登录 | 立即注册

返回顶部