这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战。
昨天在康 KunMinX 大佬的:《重学安卓:Activity 生命周期的 3 个辟谣》Linux,在加餐处看到这段:
转换后的理解:单进程场景,Activity被回收只可能是因linux系统为进程被系统回收了。
感觉不太对?因为在很久以前,遇到过这样一个场景:
App打开多个Activity,然后手机晾一边,过一段时间后(屏幕常亮),点击回退,之前的Activity空白,然虚拟机下载后重新加载了。
Alinux系统安装pp在前台,不在栈顶的Activity却被干掉,但进程还健在android平板电脑价格,如果真是这样,就和上面的理解有些出入了。
立马写个代码验证下,大概流程如下:
写个父类Activity,生命周期回调加日志打印虚拟机vmos,接着打开一个Activity,包含一个按钮,点击后依次打开多个linux系统安装Activity,最后一个加个按钮,点一下就申请一个大虚拟机一点的Byteandroid下载安装Array来模拟内存分配,看内存不足时是否会回收Activity。
测试结果如下:
App宁愿OOM,也不愿意回收Activity,鬼使神差地加上 android:largeHelinux重启命令ap=”true” ,结缓存清理果一样。
em…难道是我虚拟机对电脑伤害大吗记错缓存了???
等等!!!我好像混淆了两个东西:系统可用内存不足
和 应用可用内存不足
。
0x1、系统可用内存android平板电脑价格不足
LMK机制
Android系统中,进程的生命周期由系统控制,处于体验和性能考虑,在APP中点击android下载安装Home键或Back回退操作,并不会真的杀掉APP,进程依旧存在于内存中,这样下测试纸怀孕图片次启动此APP时就能更加快速。随着系统运行时间增长,打开APP越来越多,内存中的进程随着增多,系统的可用内存会越来越少。咋办,总不能让用户自己去杀进程吧,所以系统内置一套 回收机制,当系统可用内存达到一个 阈值,系统会根据 进程优先级 来杀掉一部分进程,释放内存linux操作系统基础知识供后续启动APP使用。
Android的这套回收机制,是基于Linux内核的OOM规则改进而来的,叫 Low Mem缓存视频变成本地视频ory Killer
,简称 LMK。
阈值 & 杀谁
通过下述两个文件配合完成,不同手机数值可能不同,以我的老爷机 魅蓝E2 为例 (Android 11的Mix2S一直Android说没权限打开此文件):
# /sys/module/lowmemorykiller/parameters/minfree
# 单位:Page页,1Page = 4KB
18432,23040,27648,46080,66560,97280
# /sys/module/lowmemorykiller/parameters/adj
0,58,117,176,529,1000
Android系统会为每个进程维护一个 ad虚拟机j(优先级)
:
- Android 6及以前称为:
oom_adj
,值范围:[-17,16],LMK要测试换算*1000/17 - Android 7后称为:
oomandroid手机_scoandroid的drawable类re_adj
,值范围:linux系统安装[-1000,1000]
然后,上面两个文件的值,其实是以一一对应的,比如:
66560 * 4 / 1024 = 260MB → 当系统可用内存减少到260MB时,会杀掉adj值大于529的进程;
18432 * 4 / 1024 = 72MB → 当系统可用内存减少到72MB,杀掉ajd值大于0的进程;
adj怎么看
直接通过命令行查看:
可以看到,adj是动态变化的,当App状态及四大组件生命周期发生改变时,都会改变它的值。常见ADJ级别如下:
- NATIVE_ADJ → -1000,init进android的drawable类程fork出来的native进程,不受system管控;
- SYSTEM_ADJ → -900,system_server进程;
- PERSISTENT_PROC_ADJ → –android下载安装800,系统persistent进程,一般不会被杀,杀了或者Carsh系统也会重新拉起;
- PERSISTEandroid的drawable类NT_SERVICE_ADJ → -700,关联着系统或persistent进程;
- FOREGRO测试抑郁症UND_APP_ADJ → 0,前台进程;
- VISIBLE_APP_ADJ → 100,可见进程;
- PERCEPTIBLE_APP_ADJ → 200,可感知进程,比如后台音乐播放;
- Bandroid下载安装ACKUP_APP_ADJ → 300,执行bindBackupAgent()过程的备份进程;
- HEAVY_WEIGHT_APP_ADJ → 400,重量级进程,system/rootdir/init.rc文件中设置;
- SERVICE_ADJ → 500,服务进程;
- HOME_APP_ADJ → 600,Home进程,类型为ACTIVITY_TYPE_HOME的应用,如Launcher;
- PREVIOUS_APP_ADJ → 700,用户上一个使用的App进程;
- SERVICE_B_ADJ → 800,B List中的Service;
- CACHED_APP_MIN_ADJ → 900,不可见进程 的adj最小值;
- CACHED_APP_MAX_ADJ缓存 → 906,不可见进程的adj最大虚拟机是什么意思值;
- UNKNOWN_ADJ → 1001,一般指将要会缓存进程,无法获取确定值;
关于ADJ计算的详细算法分析可见Gityuan大佬的:《解读Android进程优android/yunos先级ADJ算法》,干货多多,顺带从总结处捞一波进程linux是什么操作系统保活伎俩:
- UI进程与Servic测试你适合学心理学吗e进程分离,包含虚拟机是什么意思Activi虚拟机tandroid手机y的Service进程,一进后台ADJ>=900,随时可能被系统回收,分离的话ADJ=5虚拟机00,被杀的可能性降低,尤其是系统允许自启动的服务进程,必须做UI分离,避免消耗较大内存;
- 真正需要用户可感知的应用,调用startForegroundService()启用前台服务,ADJ=200;
- 进程中的S缓存ervice工作完,务必主动调用stopService或stopSelf来停止服务,避免占虚拟机安装教程用内存,浪费系统资源;
- 不要长时间绑定其他进程的service或者provider,每次使用完成后应立刻释放,避免其他进程常驻于内存;
- APP应该实现接口onTr测试抑郁症imMemory()和onLowMemory(),根据TrimLevel适当地将非必须内存在回调方法中加以释放,当系统内存紧张时会回调该接口,减少系统卡顿与杀进程频次;
- 更应在优化内存上下功夫虚拟机vmos,相同ADJ级别,系统会优先杀内存占用的进程;
问:能否把自己测试抑郁程度的问卷的App的ADJ值设置为-1000,让其杀不死? 答:不可以,虚拟机下载要有root权限才能修改adj,而且改了重启手机还是恢复的。
扯得有点远了,回到问题上:
系统内存不足时,会在内核层直接查杀进程,不会在Framework层还跟你叨逼叨看回收哪个Activity。
所以在系统这个层面,缓存单进程场景,Activity被回收只可缓存是什么意思能是因为进程被系统回收了,这句话是没毛病的,缓存文件夹名称但在应android什么意思用层面就不一定了。
0x2、应用可用内存不足
APP进程(虚拟机)的内存分配实际上是对 堆的缓存分配和释放,为了整个系统的内存控制需要,会为每个应用程序设置一个 堆的限制阈值,如果应用使用内存接近阈值虚拟机是什么意思还尝试分配内存,就很容易缓存视频变成本地视频引起OOM。
当然,缓存视频合并不会那么蠢,还要开发仔自己在Alinux操作系统基础知识PP里回收内存,虚拟机自带 GC,这里就不向去卷具体的回收算法了
假linux删除文件命令设应用内存不足真的会回收Activity,那该测试你的自卑程度怎么设测试你适合学心理学吗计?一种解法如下:
应用启动时,开一个子线程,定时轮询当前可用内存是否超过阈值,超过的话干掉Activity
那就来跟下Android是不是也是这样设计的?
Activity回收机制
跟下应用启动入口:ActivityThread → main()
跟下 attach():
这里就非常像,run()中计算:已用内存 > 3/4最大内存,就执行 releaandroid/yunosse测试你的自卑程度SomeActivities(),跟下:
所以 getService() 是获取了 IActivityTaskManager.android手机aidl接口,具体的实现类是 ActivityTaskManangerService:
继续往下跟: RootActivityContainer → releaseSomeActivitiesLocked():
跟下:WindowProcessController → getReleaseSomeActivitiesTasks()
然后再往下走就是释放Activity的代码了:Actandroid下载安装ivityStack → releaseSomeActivitiesLocked()
具体咋释linux系统放,就不往下跟了哈,测试纸怀孕图片接着跟下是怎么监控的~
内存监控机制
跟回:BinderInternal.addGcW测试工程师atcher()
这里可能看得你有点迷,但是当你理解了就会觉得很妙了:
虚拟机GC会干掉 WeakReference 的对象,在释放内存前,会调用对象的 finalize(),而这里有创建了一个新的 WeakReference 实例。下次GC,又会走一遍这里的代码,啧啧啧,相linux系统安装比起轮询高效多了
到此,应用内存不足回收Activity的流程就大概缕清了,接着可以写个代码验证下linux重启命令是否真的这样。
Demo验证
先试下两个Task的:
模拟android电子市场内存分配的页面,然后一直点~
宁愿OOM,也不回收,试试三个~
好家伙,onD缓存文件夹名称estlinux系统安装ory()了,此时按Back回退这些页面,发现走了onCre缓存文件夹名称ate(),即回收了,接着试试四个的情况缓存视频在手机哪里找:
可以,每次只回收一个Task,到此验证完毕Linux了~
0x3、结论
- 系统内存不足时,直接在内核层查杀(回收)进程,并不会考虑缓存的视频怎么保存到本地回收哪个Activity;
- 进程内存不足时,如果此进程 Activitylinux删除文件命令 Taandroid电子市场sk数 >= 3 且 使用内存超过3/4,会对 不测试纸怀孕图片可见 Task进行回收,每次回收 1个 Task,回收时机为每次gc;
参考文献:
-
解读Android进程优先级ADJ算法
-
A缓存文件夹名称ndro缓存视频合并id中的LowMemory缓存视频怎样转入本地视频Killer机制
-
And缓存视频合并app下载roid 进程回收之LowMemoryKiller原理篇
-
Android可见linux必学的60个命令APP的不可见任务栈(TaskRecord)销毁分析