Android安全模型之内存管理
白羽 2018-06-15 来源 :网络 阅读 1046 评论 0

摘要:本文将带你了解Android安全模型之安全机制,希望本文对大家学Android有所帮助。




Ashmem匿名共享内存

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等方式实现。


为有效回收,需要该内存区域的所有者通知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文件转化而来,并且进一步优化,降低内存占用。

Android的每个应用程序都有一个独立的Dalvik虚拟机实例,并且运行于独立的进程空间。Android运行时(Runtime)与虚拟机都运行于Linux操作系统之上,借助操作系统服务进行底层内存管理并访问底层设备的驱动程序。

但是,不同于Java与.NET,Android运行时同时管理进程的生命周期。为确保应用程序的响应性,可以在必要时停止甚至杀死某些进程,向更高优先级的进程释放资源。具体原则如下:

· 

应用程序的进程优先级决定哪些进程可以被杀死以释放资源,而应用程序的优先级取决于其组件的最高优先级。

· 

· 

当两个进程具备相同的优先级时,通常处于低优先级时间最长的进程先被杀死,以释放资源。

· 

· 

进程优先级同时取决于进程间的依赖关系:例如,第一个进程依赖于第二 个进程提供的服务(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值对应关系如下表:


Android安全模型之内存管理

当可用内存小于6144 * 4K = 24MB时,开始杀死所有的空进程,当可用内存小于5632 * 4K = 22MB时,开始杀死所有内容提供者与空进程。上表的设置可以通过修改以下两个文件实现:

· 

/sys/module/lowmemorykiller/parameters/adj

· 

· 

/sys/module/lowmemorykiller/parameters/minfree

· 

例如,把minfree最后一项改为32 * 1024,那么当可用内存小于128MB时,就开始杀所有的空进程。

但是,当过多进程在内存中未被释放,系统反应速度会降低,造成用户满意度降低。用户可以自行使用如task killer与task Manager之类的工具软件手动杀死不必要的后台进程与空进程,强制释放资源。

 


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程