Android中的进程是托管的,当系统进程空间紧张的时候,会依照优先级自动进行进程的回收.
由此带来三个问题:
l 回收规则: 什么时候回收与回收哪一个
l 避免误杀: 如何阻止被回收
l 数据恢复与保存: 被回收了怎么办
Android将进程分为6个等级,它们按优先级顺序由高到低
依次是:
1.前台进程( FOREGROUND_APP)
2.可视进程(VISIBLE_APP )
3. 次要服务进程(SECONDARY_SERVER )
4.后台进程 (HIDDEN_APP)
5.内容供应节点(CONTENT_PROVIDER)
6.空进程(EMPTY_APP)
特征:
1.如果一个进程里面同时包含service和可视的activity,那么这个进程应该归于可视进程,而不是service进程.
2.另外,如果其他进程依赖于它的话,一个进程的等级可以提高.例如,一个A进程里的service被绑定到B进程里的组件上,进程A将总被认为至少和B进程一样重要.
3.系统中的phone服务被划分到前台进程而不是次要服务
进程.
在android中以进程的oom_adj值也就代表了它的优先级.
oom_adj值越高代表该进程优先级越低. Init.rc中:
• setprop ro.FOREGROUND_APP_ADJ 0
• setprop ro.VISIBLE_APP_ADJ 1
• setprop ro.SECONDARY_SERVER_ADJ 2
• setprop ro.HIDDEN_APP_MIN_ADJ 7
• setprop ro.CONTENT_PROVIDER_ADJ 14
• setprop ro.EMPTY_APP_ADJ 15
Init.rc中,将PID为1的进程(init进程)的oom_adj设置
为-16:
查看本机设置:
cat /sys/module/lowmemorykiller/parameters/adj
0,1,2,7,14,15
回收时机:
Init.rc中:
•setprop ro.FOREGROUND_APP_MEM 1536
•setprop ro.VISIBLE_APP_MEM 2048
•setprop ro.SECONDARY_SERVER_MEM 4096
•setprop ro.HIDDEN_APP_MEM 5120
•setprop ro.CONTENT_PROVIDER_MEM 5632
•setprop ro.EMPTY_APP_MEM 6144
这些数字也就是对应的内存阈值,一旦低于该值,Android便开始按顺序关闭相应的进程 .
注意这些数字的单位是page. 1 page = 4 kB.
上面的六个数字对应的就是(MB): 6,8,16,20,22,24
查看现在的设置可以:
cat /sys/module/lowmemorykiller/parameters/minfree
要想重新设置该值(对应不同的需求):
echo "1536,2048,4096,5120,15360,23040">/sys/module/
lowmemorykiller/parameters/minfree
这样当可用内存低于90MB的时候便开始结束空进程. 而当可用内存低于60MB的时候才开始结束内容供应节点.
具体的回收实现在ActivityManagerService.java中的函数trimApplications()
1.首先移除package被移走的无用进程.
2.基于进程当前状态,更新oom_adj值,然后进行以下操作.
移除没有activity在运行的进程
如果AP已经保存了所有的activity状态,结束这个AP.
3.最后,如果目前还是有很多activities 在运行,那么移除那些activity状态已经保存好的activity.
更新oom_adj的值:
在ComputeOomAdjLocked中计算出进程的oom_adj,例如:
if (app == TOP_APP) {
// The last app on the list is the foreground app.
adj = FOREGROUND_APP_ADJ;
app.adjType = "top-activity";
}
Android kernel中的low memory killer
Android的Low Memory Killer根据需要(当系统内存短缺时)杀死进程释放其内存,源代码在
kernel/drivers/misc/lowmemorykiller.c
简单说就是寻找一个最合适的进程杀死,从而释放它占用的内存.
最合适:
•oom_adj越大
•占用物理内存越多
一旦一个进程被选中,内核会发送SIGKILL信号将之杀死.
for_each_process(p) {
……
if(selected == NULL || p->oomkilladj > selected->oomkilladj ||
(p->oomkilladj == selected->oomkilladj &&
tasksize > selected_tasksize))
{
selected = p;
}
}
if(selected != NULL) {
force_sig(SIGKILL, selected);
}
查看LRU列表:Adb shell dumpsys activity
由此带来三个问题:
l 回收规则: 什么时候回收与回收哪一个
l 避免误杀: 如何阻止被回收
l 数据恢复与保存: 被回收了怎么办
Android将进程分为6个等级,它们按优先级顺序由高到低
依次是:
1.前台进程( FOREGROUND_APP)
2.可视进程(VISIBLE_APP )
3. 次要服务进程(SECONDARY_SERVER )
4.后台进程 (HIDDEN_APP)
5.内容供应节点(CONTENT_PROVIDER)
6.空进程(EMPTY_APP)
特征:
1.如果一个进程里面同时包含service和可视的activity,那么这个进程应该归于可视进程,而不是service进程.
2.另外,如果其他进程依赖于它的话,一个进程的等级可以提高.例如,一个A进程里的service被绑定到B进程里的组件上,进程A将总被认为至少和B进程一样重要.
3.系统中的phone服务被划分到前台进程而不是次要服务
进程.
在android中以进程的oom_adj值也就代表了它的优先级.
oom_adj值越高代表该进程优先级越低. Init.rc中:
• setprop ro.FOREGROUND_APP_ADJ 0
• setprop ro.VISIBLE_APP_ADJ 1
• setprop ro.SECONDARY_SERVER_ADJ 2
• setprop ro.HIDDEN_APP_MIN_ADJ 7
• setprop ro.CONTENT_PROVIDER_ADJ 14
• setprop ro.EMPTY_APP_ADJ 15
Init.rc中,将PID为1的进程(init进程)的oom_adj设置
为-16:
查看本机设置:
cat /sys/module/lowmemorykiller/parameters/adj
0,1,2,7,14,15
回收时机:
Init.rc中:
•setprop ro.FOREGROUND_APP_MEM 1536
•setprop ro.VISIBLE_APP_MEM 2048
•setprop ro.SECONDARY_SERVER_MEM 4096
•setprop ro.HIDDEN_APP_MEM 5120
•setprop ro.CONTENT_PROVIDER_MEM 5632
•setprop ro.EMPTY_APP_MEM 6144
这些数字也就是对应的内存阈值,一旦低于该值,Android便开始按顺序关闭相应的进程 .
注意这些数字的单位是page. 1 page = 4 kB.
上面的六个数字对应的就是(MB): 6,8,16,20,22,24
查看现在的设置可以:
cat /sys/module/lowmemorykiller/parameters/minfree
要想重新设置该值(对应不同的需求):
echo "1536,2048,4096,5120,15360,23040">/sys/module/
lowmemorykiller/parameters/minfree
这样当可用内存低于90MB的时候便开始结束空进程. 而当可用内存低于60MB的时候才开始结束内容供应节点.
具体的回收实现在ActivityManagerService.java中的函数trimApplications()
1.首先移除package被移走的无用进程.
2.基于进程当前状态,更新oom_adj值,然后进行以下操作.
移除没有activity在运行的进程
如果AP已经保存了所有的activity状态,结束这个AP.
3.最后,如果目前还是有很多activities 在运行,那么移除那些activity状态已经保存好的activity.
更新oom_adj的值:
在ComputeOomAdjLocked中计算出进程的oom_adj,例如:
if (app == TOP_APP) {
// The last app on the list is the foreground app.
adj = FOREGROUND_APP_ADJ;
app.adjType = "top-activity";
}
Android kernel中的low memory killer
Android的Low Memory Killer根据需要(当系统内存短缺时)杀死进程释放其内存,源代码在
kernel/drivers/misc/lowmemorykiller.c
简单说就是寻找一个最合适的进程杀死,从而释放它占用的内存.
最合适:
•oom_adj越大
•占用物理内存越多
一旦一个进程被选中,内核会发送SIGKILL信号将之杀死.
for_each_process(p) {
……
if(selected == NULL || p->oomkilladj > selected->oomkilladj ||
(p->oomkilladj == selected->oomkilladj &&
tasksize > selected_tasksize))
{
selected = p;
}
}
if(selected != NULL) {
force_sig(SIGKILL, selected);
}
查看LRU列表:Adb shell dumpsys activity
当activitydemo在前台时:
包含Service的进程的优先级比较高,在computeOomAdjLocked中将其分为了两小类:
static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
if (adj > SECONDARY_SERVER_ADJ) {
adj = SECONDARY_SERVER_ADJ;
app.adjType = "started-services";
app.hidden = false;
}
}
if (adj > SECONDARY_SERVER_ADJ) {
app.adjType = "started-bg-services";
}
}
完全让进程不被kill是不可能的,我们可以通过一些操作,使进程被kill的几率变小:
1.提高进程的优先级:
后台操作采用Service形式,因为一个运行着service的进程比一个运行着后台activity的等级高。
按back键使得进程中的activity在后台运行而不是destory,需重载back按键(没有任何activity在运行的进程优先被杀).
依赖于其他优先级高的进程.
强制修改进程属性:
•在程序中设置setPersistent(true);
•在project的AndroidManifest.xml的<application>中加入属性android:persistent="true"
android:persistent(SDK)
Whether or not the application should remain running at all times . The default value is "false". Applications should not normally set this flag; persistence mode is intended only for certain system applications(phone,system).
1.使用killProcess (int pid)可以杀死指定PID的进程
public void onClick(View v) {
android.os.Process.killProcess(android.os.Process.myPid());
}
使用System.exit(0);可以达到同样的效果.
2.使用finish()可以杀死当前的activity
1. 保存资料:最好在每次Activity 运行到onPause或onStop状态时先保存资料,然后在onCreate时将资料读出来(生命周期方法).
2. OnSaveInstanceState(非生命周期方法)
onRestoreInstanceState
相关推荐
本文在ApplicationFramework与Linux内核两个层次上,以进程为粒度,对Android操作系统的进程资源回收机制进行了剖析。读者可以从本文获得对Android应用程序的生存周期的进一步理解,从而更加合理、高效地构建应用...
Android系统里面的应用程序进程有一个特点,那就是它们是被系统托管的。也就是说,系统根据需要来创建进程以及回收进程。...通过了解Android系统对应用程序进程的管理,我们就能更清楚应用程序的运行机制。
第12章 Android应用程序进程的启动过程 12.1 应用程序进程的创建过程 12.2 Binder线程池的启动过程 12.3 消息循环的创建过程 第13章 Android应用程序的消息处理机制 13.1 创建线程消息队列 13.2 线程...
本文在 Application Framework 与 Linux 内核两个层次上,以进程为粒度,对 Android 操作系统的进程资源回收机制进行了剖析。读者可以从本文获得对 Android 应用程序的生存周期的进一步理解,从而更加合理、高效地...
第12章 Android应用程序进程的启动过程 12.1 应用程序进程的创建过程 12.2 Binder线程池的启动过程 12.3 消息循环的创建过程 第13章 Android应用程序的消息处理机制 13.1 创建线程消息队列 13.2 线程消息循环...
操作系统课程设计——处理机和进程调度算法及内存分配回收机制 起步 1. clone前端仓库 2. 安装环境 3. 启动后端程序 4. 启动前端程序 5. 打开页面 http://localhost:8080/ 功能 结构 进程调度流程 1. 进程创建 2. ...
Android系统以Linux内核为基础,所以对于进程的管理自然离不开Linux本身提供的机制。例如:1.通过fork来创建进行2.通过信号量来管理进程3.通过proc文件系统来查询和调整进程状态等对于Android来说,进程管理的主要...
Android进程的回收策略5.3 保活的方法二、方法篇三、总结 前言 上文主要介绍了Andorid内存的管理机制,本文对其中的LMK机制进行深入扩展总结。 我们知道出现Crash应用闪退和崩溃一般有三个原因:ANR(程序无响应)...
5.5 Binder对象死亡通知机制..................................... 212 5.5.1 注册死亡接收通知........................................ 213 5.5.2 发送死亡接收通知...........................................
Android系统开发工程师常常需要深入理解系统的运转过程,而本书所涉及的内容可能正是他们在工作和学习中最想了解的。那些对具体模块(如Audio系统和Surface系统)感兴趣的读者 也可以直接阅读相关章节的内容。 ...
26 Android IPC 通讯机制源码分析 73 26.1 Binder通信简介: 73 26.1.1. ServiceMananger进程注册过程源码分析: 74 26.1.2. client获取remote IServiceManager IBinder接口: 75 26.1.3. client获取Service的远程...
其实和java的垃圾回收机制类似,系统 linux认证:Android系统特质不需要太多剩余内存,其实很多人都是把使用其他系统的习惯带过来来了。android大多应用没有退出的设计其实是有道理的,这和系统对进程的调度机制有...
SP是进程同步的吗?有什么方法做到同步 介绍下SurfView HashMap实现原理,ConcurrentHashMap 的实现原理 BroadcastReceiver,LocalBroadcastReceiver 区别 Bundle 机制 Handler 机制 android 事件传递机制 线程间 ...
1、JVM内存回收机制1.1回收算法标记回收算法(MarkandSweepGC)从”GCRoots”集合开始,将内存整个遍历一次,保留所有可以被GCRoots直接或间接引用到的对象,而剩下的对象都当作垃圾对待并回收,这个算法需要中断...
2.1.4. Activity 加载过程 .................. 25 2.2. Activity 的生命周期 ....................... 27 2.2.1. Activity 的生命周期图 .......... 27 2.2.2. Activity 的四种状态 .............. 29 2.2.3. ...
Android 70道面试题汇总不再愁面试 本文为开发者奉献了70道经典Android面试题加答案–重要知识点几乎都涉及到了,你还等啥,赶紧收藏吧!! 1. 下列哪些语句关于内存回收的说明是正确的? (b) A、 程序员必须创建...
垃圾回收机制 分代回收算法 垃圾回收算法 类加载过程(双亲委托) 补充: JMM(Java内存结构模型) Android基础(三天1.25-27,参考第一行代码及官方文档) 四大组件 活动的作用,生命周期(典型场景下生命周期的...