




已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Android 中LMK机制分析一、Android进程管理Android是一个多任务系统,当启动一个程序时会消耗一定的时间。为了加快运行速度,当退出一个程序时,Android并不会立即杀掉它。这样当用户重新运行该程序时,可以很快地启动。但随着系统中保留的程序越来越多,内存肯定会出现不足,此时就有了Android的低内存管理(Low Memory Killer)机制。Android根据进程的重要性,将进程分为以下几类: 前台进程(forground process),用户正在做的事情相关的进程,具体包括:l 正在和用户交互的Activty,即该Activity的onResume()已经执行过。l 包含一个service,该service正在服务于和用户交互的Activity。l 包含一个service,该service正在执行onCreate(),或者onStart(),onDestroy()。l 包含一个BroadcastReceiver,正在执行onRceive()函数 可见的进程(visible process),尽管没有和用户交互,但是却可以影响用户所能看得到的内容。l 尽管没有包含和用户交互的Activity,但是用户却可以看得见该Activity的窗口,比如一个Activity上面弹出一个对话框的情况l 包含一个service,该service服务于可见的Activity。 服务进程(service proces),凡是使用startService()所启动的service对象,其所在的进程都称之为服务进程。当然,如果该service满足上面两个优先级中的条件,则会上升为相应的优先级 后台进程(background process),不满足以上任何一个条件的进程,同时该进程中还包含一些不可见的Activity,这些进程不影响正在和用户交互的Activity。 空进程(empty process),进程中不包含任何component,包括Activity、service、receiver对象。之所以还保留这些进程的原因是为了减少重新创建进程的开销。以上每个进程都会有个oom_adj值。二、oom_adj的值是如何赋予的进程的adj类型,可以在ActivityManagerService中清楚的看到: static final int EMPTY_APP_ADJ; static final int HIDDEN_APP_MAX_ADJ; static final int HIDDEN_APP_MIN_ADJ; static final int HOME_APP_ADJ; static final int BACKUP_APP_ADJ; static final int SECONDARY_SERVER_ADJ; static final int HEAVY_WEIGHT_APP_ADJ; static final int PERCEPTIBLE_APP_ADJ; static final int VISIBLE_APP_ADJ; static final int FOREGROUND_APP_ADJ; static final int CORE_SERVER_ADJ = -12; static final int SYSTEM_ADJ = -16; ActivityManagerService定义各种进程的oom_adj,CORE_SERVER_ADJ代表一些核心的服务的omm_ad,数值为-12,这类进程永远也不会被杀死。其他未赋值的都在static块中进行了初始化,是通过system/rootdir/init.rc进行配置的:在init.rc中:# Define the oom_adj values for the classes of processes that can be# killed by the kernel. These are used in ActivityManagerService. 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# Define the memory thresholds at which the above process classes will# be killed. These numbers are in pages (4k). 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 6144oom_adj内存警戒值(以4K为单位)01536120482409675120145632156144配置文件有如下两个:/sys/module/lowmemorykiller/parameters/adj/sys/module/lowmemorykiller /parameters/minfreeowmeme_adj中各项数值代表阈值的警戒级数,lowmem_minfree代表对应级数的剩余内存。三、Low Memory Killer(LMK)机制进程的oom_adj值由ActivityManagerService根据运行在进程里面的组件的状态来计算,取值范围为-16,15,oom_adj的值越小,就越不容易被杀死。内存紧张时LMK基于oom_adj值来决定是否要回收一个进程。ActivityManagerService和WindowManagerService在特定情况下也会将进程回收。LMK的回收进程策略:当系统内存小于i时,在oom_adj值大于等于j的进程中,选择一个oom_adj值最大并且消耗内存最多的进程来回收class ProcessList / These are the various interesting memory levels that we will give to/ the OOM killer. Note that the OOM killer only supports 6 slots,so we/ cant give it a different value for ever possible kind of process.private final int mOomadj = new int FOREGROUND_APP_ADJ /*0*/,VISIBLE_APP_ADJ /*1*/,PERCEPTIBLE_APP_ADJ /*2*/,BACKUP_APP_ADJ /*4*/,HIDDEN_APP_MIN_ADJ /*9*/,HIDDEN_APP_MAX_ADJ /*15*/,;/ These are the low-end OOM level limits. This is appropriate for an/ HVGA or amller phone with less than 512KB. Values are in KS.Private final long mOomHinFreelow = new long 8192,12288,16384,24576,28672,32768;/ These are the high-end OOM level limits. This is appropriate for a/ 1280x800 or larger screen with arount 1GB RAM. Values are in KS.Private final long mOomMinFreeHigh = new long 32768,40960,49152,57344,65536,81920;ActivityManagerService在以下情况下会更新应用程序进程的oom_adj值,以及杀掉那些已经被卸载了的App所运行的应用程序进程:l ActivityStopped:停止Activityl setProcessLimit:设置进程数量限制l unregisterReceiver:注销Broadcast Receiverl finishReceiver:结束Broadcast Receiver首先根据阈值表确定当前的警戒级数,则高于警戒级数的进程是待杀的范围。然后遍历所有进程的oom_adj值,找到大于min_adj的进程,若找到多个,则把占用进程最大的进程存放在selected中。 WindowManagerService在处理窗口的过程中发现Out Of Memroy时,也会通知ActivityManagerService杀掉那些包含窗口的process。Ams(Activity manager service)运行在Java环境中,而Android采用Dalvik虚拟机,应用程序和Ams运行在两个独立的虚拟机中,Ams并不会知道应用程序的内存分配情况。那内存是怎么管理的呢?在Android中运行一个Low Memory Killer进程,该进程启动时会首先在Linux内核中把自己注册为一个OOM Killer,即当Linux内核的内存管理模块检测到系统内存低的时候就会通知己经注册的OOM进程,然后这些OOM Killer就可以根据各种规则进行内存释放。当内存满足低的条件时,Linux内核管理模块通知OOM Killer,Killer则根据Ams所告知的优先级,强制退出优先级低的应用程序。图1:Android中内存OOM机制示意图Low Memory Killer是以内核驱动的形式实现的,该实现位于drivers/misc/lowmemorykiller.c中,通过注册Cache Shrinker实现。Cache Shrinker是标准Linux kernel回收页而的一种机制,它由内核线程kswapd监控,当空闲内存页面不足时,kswapd会调用注册的Shrinkcr回调函数,来回收内存页面。Lowmem_shrink是这个驱动的核心实现,当内存不足时就会调用Lowmem_shrink方法来杀掉某些内存。Lowmem_shrink用两个数组作为选择bad进程的依据.定义如下:static int lowmem_adj6=0,1,6,12;static int lowmem_adj_size=4;static size_tlowmem_minfree6=3*512,2*1024,4*1024,16*1024;lowmem_minfree。保存空闲内存的阀值,单位是一个页面4 Kh,lowmem_adj保存每个阀值对应的优先级。lowmem_shrink首先计算当前空闲内存的大小,如果小于某个阀值,则以该阀值对应的优先级为基准,遍历各个进程,计算每个进程占用内存的大小,找出优先级大于基准优先级的进程,在这些进程中选择优先级最大的杀死。如果优先级相同,则选择占用内存最多的进程。lowmem_shrink杀死进程的方法是向进程发送一个不可以忽略或阻塞的SIGKILL信号:force_sig(SIGKILL,selected).四、Android内存优化研究Android内存管理机制主要足针对进程的优先级和内存占用情况来对进程进行管理的,所以对内存管理的优化也主要体现在对进程阀值的设定上。Android的Low Memory Killer机制基本上可以满足普通用户的需求,但是针对于某些特定用户就需要对特定程序进行某些设置,从而手动地参与内存管理。对进程的优化主要设置各类进程的阀值,系统阀值存在的问题包括:第一,各类进程管理策略的阀值相当接近,在实际程序运行中,很容易导致多种类型的进程同时被关闭;第二,阀值上限较低,一般手机启动后,可用内存在50100 MB左右,但随着手机的使用,内存会逐渐减小,最后降低到24 MB左右,但24 MB相对较低,会降低系统的反应速度。优化原则:l 拉开各进程的阀值层次,使得进程管理机制能更有效地工作;l 提高阀值上限,空出更多的空余内存,以提升系统整体的运行速度;l 前台进程、可见进程和服务进程是与用户体验息息相关的内容,这部分的进程管理策略要相对保守,给这些进程留下足够的运行空间;l 压榨无用进程,腾出内存空间给主要程序使用。当然更好的内存优化应该是尽量防止OOM。容易造成oom的情况:1、不恰当的使用static关键字。静态变量属于类而不是对象,所以使用static保存大资源(比如Context)非常容易造成oom。解决方案:尽量不要使用static 变量保存大资源(比如Context等)2、内部类线程引发oom。 线程的生命周期不可控,在线程没有完成run方法之前线程不会被销毁,同时由于采用内部类产生的线程同时用保存Activity的引用。同理使用Activity的内部类Asyncatask也容易造成oom解决方案:l 将内部类线程改为静态内部类l 在线程内部使用弱引用保存Context引用,解决模型如下:(转)public abstract class WeakAsyncTask extends AsyncTask protected WeakReference mTarget; public WeakAsyncTask(WeakTarget target) mTarget = new WeakReference(target); /* inheritDoc */ Override protected final void onPreExecute() final WeakTarget target = mTarget.get(); if (target != null) this.onPreExecute(target); /* inheritDoc */ Override protected final Result doInBackground(Params. params) final WeakTarget target = mTarget.get(); if (target != null) return this.doInBackground(target, params); else return null; /* inheritDoc */ Override protected final void onPostExecute(Result result) final WeakTarget target = mTarget.get(); if (target != null) this.onPostExecute(target, result); protected void onPreExecute(WeakTarget target) / No default action protected abstract Result doInBackground(WeakTarget target, Params. params); protected void onPostExecute(WeakTarget target, Result result) / No default action 3、Bitmap使用,使用数量多的Bitmap极易造成oom解决方案:l 及时销毁Bitmap,bitmap不在使用的时候及时Recyclel 设定采样率,使用BitmapFactory处理Bitmap再使用l 使用软应用,如果使用一个Bitmap却没有保留他的引用那么则没有办法调用recycle方法,使用软应用可以使bitmap在内存不足的时候得到释放4、资源对象没有及时关闭资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,我们在不使用的时候,应该及时关闭它们,以便它们的缓冲及时回收内存。它们的缓冲 不仅存在于java虚拟机内,还存在于java虚拟机外。如果我们仅仅是把它的引用设置为null,而不关闭它们,往往会造成内存泄露。因为有些资源性对象,比如SQLiteCursor(在析构函数finalize(),如果我们没有关闭它,它自己会调close()关闭),如果我们没有关闭它,系统在
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 健身设施建设 合同范本
- 关于团结的演讲稿(汇编5篇)
- 关于团结的演讲稿范文(5篇)
- 智慧城市建设对环境影响评价
- 2025年生命体征试题及答案
- 2025年沈阳市小学考试试题及答案
- 2025年山西省太原市事业单位教师招聘考试教育类《综合知识》真题库及答案
- 2025年山东省招聘储备教师教育理论、教育基础知识+英语自测试题及答案
- CN223041083U 一种具有密封结构的防漏式睫毛膏管 (广东品凡派塑胶实业有限公司)
- CN120277914A 基于多源声波数据的动态温度场实时重建方法及系统 (郑州轻工业大学)
- T-JSYLA 00007-2022 江苏省智慧公园建设指南
- 湘教版地理必修一知识点复习
- 热控安装工程施工方案
- 医院水、电、气故障报修、排查、处理流程1
- 八年级上册物理 第一章 第一节长度和时间的测量课件
- 数控加工中心培训课件
- 开关电源测试表格
- 《思想政治教育专业导论》课程教学大纲
- 产品可追溯性模拟演练(成品-原料)记录
- 中国—东盟自贸区
- 安全帽试验作业指导书实施细则
评论
0/150
提交评论