Ashmem匿名共享内存java
Android的匿名共享内存(Ashmem)机制基于Linux内核的共享内存,可是Ashmem与cache shrinker关联起来,增长了内存回收算法的注册接口,所以Linux内存管理系统将再也不使用内存区域加以回收。Ashmem之内核驱动的形式实现,在文件系统中建立/dev/ashmem设备文件。若是进程A与进程B须要共享内存,进程A可经过open打开该文件,用ioctl命令ASHMEM_SET_NAME和ASHMEM_SET_SIZE设置共享内存的名称和大小。mmap使用handle得到共享的内存区域;进程B使用一样的handle,由mmap得到同一块内存。handle在进程间的传递可经过Binder等方式实现。android
为有效回收,须要该内存区域的全部者通知Ashmem驱动。经过用户,Ashmem驱动程序,以及Linux内存管理系统的协调,使内存管理更适应嵌入式移动设备内存较少的特色。Ashmem机制辅助内存管理系统来有效管理再也不使用的内存,同时经过Binder进程通讯机制实现进程间的内存共享。算法
Ashmem不但以/dev/ashmem设备文件的形式适应Linux开发者的习惯,并且在Android系统运行时和应用程序框架层提供了访问接口。其中,在系统运行时提供了C/C++调用接口,在应用程序框架层提供了Java调用接口。而实际上,应用程序框架层的Java调用接口是经过JNI方法来调用系统运行时的C/C++调用接口的,最后进入到内核空间的Ashmem驱动程序中。安全
LMK机制框架
Android的软件协议栈由操做系统内核,中间件与应用程序组成。虽然基于Linux操做系统内核,android进程的内存管理与Linux仍有区别。Android的应用程序由java语言编写,运行于Java虚拟机之上,可是,Android的java虚拟机Dalvik与传统的Java虚拟机是有区别的。Dalvik采用基于寄存器的虚拟机优化实现,确保多个虚拟机实例同时运行,借助Linux内核服务,实现安全保护,线程管理,底层进程与内存管理等功能。Dalvik虚拟机运行.dex格式的Dalvik可执行文件。.dex格式由android工具将java格式的class文件转化而来,而且进一步优化,下降内存占用。ide
Android的每一个应用程序都有一个独立的Dalvik虚拟机实例,而且运行于独立的进程空间。Android运行时(Runtime)与虚拟机都运行于Linux操做系统之上,借助操做系统服务进行底层内存管理并访问底层设备的驱动程序。函数
可是,不一样于Java与.NET,Android运行时同时管理进程的生命周期。为确保应用程序的响应性,能够在必要时中止甚至杀死某些进程,向更高优先级的进程释放资源。具体原则以下:工具
应用程序的进程优先级决定哪些进程能够被杀死以释放资源,而应用程序的优先级取决于其组件的最高优先级。优化
当两个进程具有相同的优先级时,一般处于低优先级时间最长的进程先被杀死,以释放资源。spa
进程优先级同时取决于进程间的依赖关系:例如,第一个进程依赖于第二 个进程提供的服务(Services)或内容提供者(Content Provider),则第二个进程至少具有与第一个进程一样的优先级。
Android系统能够同时运行多个应用程序。因为启动与运行一个应用程序须要必定的时间开销,为了加快运行速度,Android并不会当即杀死一个退出的程序,而是让它驻留在内存中,以便下次运行时迅速启动。可是,随着程序愈来愈多,内存会出现不足。当Android系统须要某一进程释放资源为其余进程所用时,系统使用所谓的“LowMemoryKiller”杀死进程以释放资源。LowMemoryKiller在Linux内核中实现,按程序的重要性来决定杀死哪个应用。所以,必须妥善设置进程的优先级,不然该进程可能在运行过程当中被系统杀死。
Android自动管理打开并运行于后台的应用程序,单个程序都有一个oom_adj值,值越小,优先级越高,被杀死的可能性越低。Android将程序的重要性分红几类。
1. 前台进程(Active Process):oom_adj值为0。前台进程为正在与用户交互 的应用程序。为响应前台进程,Android可能要杀死其余进程以收回资源。前台进程分为如下几类:
活动(Activity)正在前台接收用户输入事件。
活动,服务与广播接收器正在执行一个onReceive事件处理函数。
服务正在执行onStart,onCreate或onDestroy事件处理函数。
2. 已启动服务的进程(Started Service Process):oom_adj值为0。这类进程包含一个已启动的服务。服务并不直接与用户输入交互,所以服务的优先级低于可见活动的优先级。可是,已启动服务的进程仍然被认为是前台进程,只有在活动及可见活动须要资源时,已启动服务的进程才会被杀死。
3. 可见进程(Visible Process):oom_adj值为1。活动(Activity)是可见的,但并不在前台,或者不响应用户的输入。例如,Activity被非全屏的Activity或透明的Activity所遮挡。包含此类可见Activity的进程被称为可见进程。只有在很是少有的极端状况下,此类进程才会被杀死以释放资源。
4. 后台进程(Background Process):oom_adj值为2。这类进程不包含任何可见的活动与启动的服务。一般大量后台进程存在时,系统会采用(last-seen-firest-killl)后见先杀的方式,释放资源供前台进程使用。
5. 主界面(Home Process):oom_adj值为4。
6. 隐藏进程(Hidden Process):oom_adj值为7。
7. 内容提供者(Content Provider):oom_adj值为14。
8. 空进程(Empty Process):oom_adj值为15。既不提供服务,也不提供内容的进程。
Android系统一般有一个内存警惕值与oom_adj值的对应表:每一个内存警惕值对应一个oom_adj值。当系统内存低于警惕值时,全部大于oom_adj值的进程均可被杀死!内存警惕与oom_adj值对应关系以下表:
进程各种 |
oom_adj值 |
内存警惕值(以4KB为单位) |
前台进程/服务进程 |
0 |
1536 |
可见进程 |
1 |
2048 |
后台进程 |
2 |
4094 |
隐藏进程 |
7 |
5120 |
内容提供者 |
14 |
5632 |
空进程 |
15 |
6144 |
当可用内存小于6144 * 4K = 24MB时,开始杀死全部的空进程,当可用内存小于5632 * 4K = 22MB时,开始杀死全部内容提供者与空进程。上表的设置能够经过修改如下两个文件实现:
/sys/module/lowmemorykiller/parameters/adj
/sys/module/lowmemorykiller/parameters/minfree
例如,把minfree最后一项改成32 * 1024,那么当可用内存小于128MB时,就开始杀全部的空进程。
可是,当过多进程在内存中未被释放,系统反应速度会下降,形成用户满意度下降。用户能够自行使用如task killer与task Manager之类的工具软件手动杀死没必要要的后台进程与空进程,强制释放资源。