专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

Android性能优化OOM内存管理ADJ

  前言
  OOMADJ(OutofMemoryAdjustment)是android系统在内存不足情况下进行内存调整的重要参数。在处理app启动速度的时候,可以设置主线程的优先级,保证主线程占用的cpu足够久。进程的oomadj,决定了当内存不够的时候,lmk会根据oomadj的大小依次释放内存。在前面介绍Activity页面启动路程过程中见到了更新adj的相关方法,但是没有深入介绍,这里分析一些相关实现。更新adjfinalbooleanrealStartActivityLocked(ActivityRecordr,ProcessRecordapp,booleanandResume,booleancheckConfig)throwsRemoteException{r。startFreezingScreenLocked(app,0);更新LurmService。updateLruProcessLocked(app,true,null);更新ADJmService。updateOomAdjLocked();xxxx通过Binder远程调用Activity的onCreateonResume等生命周期app。thread。scheduleLaunchActivity(newIntent(r。intent),r。appToken,System。identityHashCode(r),r。info,newConfiguration(mService。mConfiguration),r。compat,r。task。voiceInteractor,app。repProcState,r。icicle,r。persistentState,results,newIntents,!andResume,mService。isNextTransitionForward(),profilerInfo);returntrue;}
  在启动页面的流程中存在一个名为realStartActivityLocked的方法,这个方法会通过Binder远程调用Activity的onCreate,onResume等生命周期方法,在回调生命周期之前调用了updateLruProcessLocked以及updateOomAdjLocked这两个方法。这两个方法都与进程的优先级有关系。updateLruProcessLockedfinalvoidupdateLruProcessLocked(ProcessRecordapp,booleanactivityChange,ProcessRecordclient){hasActivity用来表示某个app中是否包含activity组件1。app本身确实包含activity组件;2。app本身有service,并且有另外一个含有activity的app链接到此app的service上;3。该app启动serivce的时候带有标记BINDTREATLIKEACTIVITY。finalbooleanhasActivityapp。activities。size()0app。hasClientActivitiesapp。treatLikeActivity;目前,并没有考虑进程中是否含有Service因此,虽然理论上定义了Service相关的进程分类,但并没有实现对应的管理策略在以下代码中,hasService一直为falsefinalbooleanhasServicefalse;notimplyet。app。services。size()0;if(!activityChangehasActivity){Theprocesshasactivities,soweareonlyallowingactivitybasedadjustmentstomoveit。Itshouldbekeptinthefrontofthelistwithotherprocessesthathaveactivities,andwedontwantthosetochangetheirorderexceptduetoactivityoperations。return;}计数器,记录该函数被调用了多少次,也就是LRU被更新了多少次。mLruSeq;finallongnowSystemClock。uptimeMillis();app。lastActivityTimenow;Firstaquickreject:iftheappisalreadyatthepositionwewillputit,thenthereisnothingtodo。if(hasActivity){finalintNmLruProcesses。size();如果要插入的app已经在mLruProcesses顶端了,就不用插入了if(N0mLruProcesses。get(N1)app){if(DEBUGLRU)Slog。d(TAG,Notmoving,alreadytopactivity:app);return;}}else{将其插入到Service的开头if(mLruProcessServiceStart0mLruProcesses。get(mLruProcessServiceStart1)app){if(DEBUGLRU)Slog。d(TAG,Notmoving,alreadytopother:app);return;}}intlruimLruProcesses。lastIndexOf(app);persistentapp,这部分app不会被杀死,永远在运行,if(app。persistentlrui0){如果persistentapp已经在列表里面了那么不作处理。Wedontcareaboutthepositionofpersistentprocesses,aslongastheyareinthelist。if(DEBUGLRU)Slog。d(TAG,Notmoving,persistent:app);return;}lrui0,说明LRU中之前记录过当前进程的信息即该进程不是新创建的那么在调整之前,需要先将之前的记录删除if(lrui0){if(lruimLruProcessActivityStart){此进程没有包含ActivitymLruProcessActivityStart;}if(lruimLruProcessServiceStart){此进程没有服务,是个其他类型的进程mLruProcessServiceStart;}移除进程,后面会再次添加mLruProcesses。remove(lrui);}nextIndex主要用于记录当前进程绑定的Service或ContentProvider对应的进程,应该插入的位置(对应进程中仅含有Service和Provider时才需要处理)后文将看到该值的使用情况intnextIndex;if(hasActivity){finalintNmLruProcesses。size();if(app。activities。size()0mLruProcessActivityStart(N1)){该App没有Activity,但是有一个有Activity的app启动了该App的一个Service。mLruProcessActivityStart(N1)表示App不是当前在显示的页面。mLruProcesses。add(N1,app);举一个具体的例子,当前显示的AppA打开属于另一个AppB的Service,此时当前显示的AppA就在N这个位置,被打开的Service所在的AppB在N1这个位置。TokeepitfromspammingtheLRUlist(bymakingabunchofclients),wewillpushdownanyotherentriesownedbytheapp。下面的代码,是为了调整不同用户之间的公平性;当前用户新启动了一个进程,将该用户对应的其它进程,适当往前挪动一下(优先被kill)finalintuidapp。info。uid;为了防止某个app中的service绑定了一群client从而导致LRU中顶部大部分都是这些client,这里需要将这些client往下移动,以防止某些app通过和某个app的service绑定从而提升自己在LRU中位置。for(intiN2;imLruProcessActivityStart;i){ProcessRecordsubProcmLruProcesses。get(i);遍历找到第一个与app的uidif(subProc。info。uiduid){if(mLruProcesses。get(i1)。info。uid!uid){交换i与i1位置的进程,ProcessRecordtmpmLruProcesses。get(i);mLruProcesses。set(i,mLruProcesses。get(i1));mLruProcesses。set(i1,tmp);i;}还是以上面那个例子为例。A在打开B之后有打开另一个AppC的Service。此时A,B,C的位置是N,N1,N2,由于BC的uid一样,此时B也就是先打开的服务可能会一直向后移动直到mLruProcessActivityStart这个位置,}else{Agap,wecanstophere。break;}}}else{Processhasactivities,putitattheverytipsytop。if(DEBUGLRU)Slog。d(TAG,AddingtotopofLRUactivitylist:app);进程具有activity,在N位置添加,也就是在栈顶添加,此时app一般就是要显示的app。mLruProcesses。add(app);}nextIndexmLruProcessServiceStart;}elseif(hasService){Processhasservices,putitatthetopoftheservicelist。不走这个分支,hasService总是false,if(DEBUGLRU)Slog。d(TAG,AddingtotopofLRUservicelist:app);mLruProcesses。add(mLruProcessActivityStart,app);nextIndexmLruProcessServiceStart;mLruProcessActivityStart;}else{Processnototherwiseofinterest,itgoestothetopofthenonservicearea。一般走这里,intindexmLruProcessServiceStart;一般情况下clientnull,这个分支不走if(client!null){client表示一个另一个进程,此进程可能具有页面,也可没有,但是这个进程打开了一个只有服务得进程,那么只有服务的进程需要排在client进程的下面Ifthereisaclient,dontallowtheprocesstobemoveduphigherinthelistthanthatclient。intclientIndexmLruProcesses。lastIndexOf(client);if(DEBUGLRUclientIndex0)Slog。d(TAG,Unknownclientclientwhenupdatingapp);if(clientIndexlrui){Dontallowtheclientindexrestrictiontopushitdownfartherinthelistthanitalreadyis。clientIndexlrui;}if(clientIndex0indexclientIndex){此时表示client也是一个只有服务的进程而且client在app进程的下面,此时需要调整添加app进程的位置,调整之后app的位置是clientIndex,client的位置是clientIndex1indexclientIndex;}}if(DEBUGLRU)Slog。d(TAG,AddingatindexofLRUlist:app);添加进程mLruProcesses。add(index,app);nextIndexindex1;mLruProcessActivityStart;mLruProcessServiceStart;}Iftheappiscurrentlyusingacontentproviderorservice,bumpthoseprocessesaswell。本进程打开了service或者是ContentProvider,如果这个Service或者ContentProvider是定义自己App里面那么此处没啥影响。如果是定义在另一个App里面则有影响。这里的微调分为两种情况:第一是service所在的进程的位置调整到本进程之后,第二是将ContentProvider所在的进程位置调整到本进程之后。调整的方式都是使用updateLruProcessInternalLocked方法,for(intjapp。connections。size()1;j0;j){ConnectionRecordcrapp。connections。valueAt(j);if(cr。binding!null!cr。serviceDeadcr。binding。service!nullcr。binding。service。app!nullcr。binding。service。app。lruSeq!mLruSeq!cr。binding。service。app。persistent){nextIndexupdateLruProcessInternalLocked(cr。binding。service。app,now,nextIndex,serviceconnection,cr,app);}}for(intjapp。conProviders。size()1;j0;j){ContentProviderRecordcprapp。conProviders。get(j)。provider;if(cpr。proc!nullcpr。proc。lruSeq!mLruSeq!cpr。proc。persistent){nextIndexupdateLruProcessInternalLocked(cpr。proc,now,nextIndex,providerreference,cpr,app);}}}privatefinalintupdateLruProcessInternalLocked(ProcessRecordapp,longnow,intindex,Stringwhat,Objectobj,ProcessRecordsrcApp){srcApp打开app的一个Service或者ContentProviderapp。lastActivityTimenow;如果有Activity,不做调整if(app。activities。size()0){Dontwanttotouchdependentprocessesthatarehostingactivities。returnindex;}如果进程不在mLruProcess中,就返回intlruimLruProcesses。lastIndexOf(app);if(lrui0){Slog。wtf(TAG,AddingdependentprocessappnotonLRUlist:whatobjfromsrcApp);returnindex;}如果进程的位置高于需要调整的位置,不做调整if(lruiindex){Dontwanttocausethistomovedependentprocessesbackinthelistasiftheywerelessfrequentlyused。returnindex;}如果目前进程的位置比mLruProcessActivityStart还要高,不调整if(lruimLruProcessActivityStart){Dontwanttotouchdependentprocessesthatarehostingactivities。returnindex;}走到这里表示lruiindexlruimLruProcessActivityStart。把App调整到index1的位置mLruProcesses。remove(lrui);if(index0){index;}if(DEBUGLRU)Slog。d(TAG,MovingdepfromlruitoindexinLRUlist:app);mLruProcesses。add(index,app);returnindex;}例如当前显示的AppA打开了一个AppB的一个Service,由于AppA是当前显示的App,优先级最高,此时A使用的Service所在的AppB也应该尽可能的提高等级避免内存回收,此时会将AppB放到mLruProcessServiceStart这个位置。假如非得回收内存的话会先回收0mLruProcessServiceStart之间的进程占据的内存。
  mLruProcesses是一个列表,其本分为三个部分0mLruProcessServiceStart用于保存其他进程;
  mLruProcessServiceStartmLruProcessActivityStart用于保存服务进程,但是实际情况下这个区域的大小是0,也即是服务进程实际也是放在了其他进程区域。
  mLruProcessActivityStartend保存的有Activity的进程。每次添加Activity进程都是在end位置,在mLruProcessServiceStart位置添加服务进程或者其他进程。
  位置越大的进程优先级越高越不容易被回收。
  每次调用updateLruProcessLocked调整某个进程的位置的时候也会调整与之相关的进程的位置,例如调整进程A的位置就要顺便调整A启动的Service以及ContentProvider所在的进程位置。
  版权声明:本文为CSDN博主昨夜西风在吹的原创文章,遵循CC4。0BYSA版权协议,转载请附上原文出处链接及本声明。原文链接:https:blog。csdn。netqq31469589articledetails11796935
  以上就是有关Android内存管理ADJ讲解;有关更多Android开发技术性能调优学习;大家私信:手册《Android性能优化手册》获取相关学习资料。结尾(心灵的鸡汤)
  我相信,梦想只要能坚持,就一定能成为现实。就像代表着永恒的天蓝色。就让这小小的梦想的种子,在我们心中,渐渐发芽、成长,在心中开出美丽、绚烂的花。让我们努力飞翔,乘着梦想的翅膀,飞到成功的远方。

悲壮!杨鸣与4核缺席,辽篮16分完胜,老帅仅8人可用,惨吞10连败头条创作挑战赛118102!卫冕冠军辽宁男篮以16分的优势,大胜了残阵出击的天津男篮,赢得十分悲壮。杨鸣不在,4大核心韩德君郭艾伦张镇麟李晓旭都打不了,辽宁男篮一度领先30分,可惜宣泄?深夜回复粉丝疑似不满杜锋!四大细节证明赵睿离队传言不假头条创作挑战赛近日广东男篮赵睿因赛场漫不经心,遭到杜指导弃用一事也是闹得沸沸扬扬,不少媒体人纷纷传言赵睿或将会离队。那么赵睿是否真的会离队呢?笔者认为四大细节证明他离队传言并非空穴2026年世界杯确定2022年第22届卡塔尔世界杯己落下维幕。国际足联又宣布2026年第二十三届世界杯举办国已确定,由三个国家共同举办,分别是美国,加拿大,墨西哥三国。十六座城市参与。美国十一座,加拿世界杯落幕,28天64场比赛,C罗失意梅西得意,一句话点评32强!又一届世界杯落幕了,从11月20号到12月19号,卡塔尔世界杯32强轮番亮相在这个大舞台上,有球队不断创造奇迹,有球队让人大跌眼镜,有的球员身价暴涨,有的球员泪洒赛场新冠疫情下的这决赛先生迪马利亚是梅西在阿根廷队最好配角!只要迪马利亚在决赛中进球,阿根廷队就夺冠!迪马利亚真是天使,给阿根廷队带来好运气!卡塔尔世界杯决赛对法国队,第23分钟梅西点球首开纪录。老到而冷静地过掉登贝莱,创造点球机会的是迪马阿根廷夺冠功臣大马丁,巅峰从被阿森纳抛弃开始,最大法宝心理战埃米利亚诺马丁内斯,数次从死亡线上把阿根廷队拉回重新续命的守门员,每次在点球大战前都会肯定地告诉队友他会扑出点球的男人,总是神神叨叨地在对手罚点球时碎嘴子的疯子,跑起路来肥肉都要跳世界杯已经落幕,VR的中场战事才刚开始盘点世界杯看球科技进化史这届世界杯的快乐是PICO给的作者徐珊编辑漠影这是我感受到科技感最强的一届世界杯。就在今天凌晨,梅西首次捧起了属于他的大力神杯!2022年卡塔尔世界杯,不但政治经济危机交织,阿根廷得到了一场亟须的胜利当地时间12月18日,在卡塔尔世界杯足球赛决赛中,阿根廷队通过点球大战击败法国队,夺得世界杯冠军。这一刻,与卡塔尔相隔半个地球的阿根廷举国陷入了狂欢的海洋。就像在天堂一般。阿根廷球詹姆斯冲第五冠?曝湖人3换2报价特纳希尔德,甘愿舍弃两个首轮签北京时间12月19日,NBA常规赛继续进行,在刚刚结束的一场焦点战中,洛杉矶湖人队以119117险胜华盛顿奇才队,取得两连胜,同时送给奇才队十连败。这场比赛戴维斯缺阵,湖人赢得并不35岁本泽马宣布退出法国国家队我们的故事今天结束了北京时间12月19日晚,金球先生本泽马在自己的社交媒体上发文,宣布退出法国国家队。本泽马在社交媒体上发文写道我付出过努力,也犯下过错误,是这些成就了今天的我,我为此感到自豪。我写下梅西举奖杯时穿的黑纱衣是什么?12月19日,梅西带领阿根廷队在卡塔尔世界杯上夺冠,真的太不容易了!小快在这祝贺阿根廷队获得冠军,也祝贺梅西加冕球王!但镜头给到颁奖仪式上时,眼尖的球迷发现国际足联主席与卡达尔官员
威尔士公开赛,7场40宾汉姆出局,田鹏飞晋级丁俊晖今晚出战威尔士公开赛首日,绝大部分场次进行的是前16球员的延期资格赛。结果,比分悬殊的比赛较多,40一共有7场,41达到8场。7场408场41卫冕冠军乔佩里手感火热,40胜马克金火箭奥沙利勇士队战胜奇才队,汤普森2745,科尔承诺他将参加背靠背比赛鹈鹕队开拓者队和森林狼队都获得比赛胜利,这三支球队的胜场相近,他们和勇士队是竞争对手,所以压力来到勇士队这边了,以目前的形势来看,至少有多支我们喜爱的球队将无缘季后赛,其中就可能包记者足协或另聘主帅带亚运队,扬科维奇本应12强赛后期接班李铁直播吧2月14日讯据记者裴力报道,若扬科维奇执教国足,中国足协有可能聘请其他主帅带队征战亚运会的赛事。男足亚运队13日下午与乙级队丹东腾跃进行了一场教学赛,两队最终11战成平局。按脾虚比肾虚或更可怕?常做4件事或有助健脾运脾导语肥胖可以说是我们迈向小康社会的绊脚石,过去,人们的经济条件很差,所以他们很瘦,如今,我们的生活条件越来越好,所以吃的食物狠丰富,这就导致了很多人出现肥胖的现象,可是肥胖会导给我今天,互联网的瓜都在这了!1昨天,有网友咨询笔者。卦卦,有博主爆料了一条的新闻,这事是真的还是人造新闻?先给大家说结论,这事是真的。原始出处为某商业新媒体记者的私人社交软件。只不过,该记者还补充了一句还好演老外拆解华为畅享50除了麒麟710A,其他自研芯片也不少在美方的封锁之下,华为手机遭遇了芯片危机,出货量迅速从巅峰期的2亿台,下降为千万台级别。2021年华为手机出货量仅为3000多万台,在2022年华为手机出货量占国内市场的7。9,按抗癌抗氧化多吃红薯的好处多吃红薯的好处抗氧化剂丰富111并非所有的红薯都是橙色的。它们的皮肤和内部可以是白色黄色棕色红色粉红色和紫色。颜色的范围为餐桌带来了不同的营养。紫肉红薯被认为含有超高水平的抗氧化剂武夷山五夫镇油菜花开迎春放百亩花田迎客来武夷山五夫镇百亩油菜花竞相绽放东南网记者郑正华摄2月18日,在武夷山五夫镇种植的百亩油菜花,提前竞相绽放,引得周边游客纷至沓来赏花游玩。百亩油菜花竞相绽放东南网记者郑正华摄游客打卡乾安县余字乡张字村盐碱地里草莓甜来源吉林农业农村厅市县要闻走进乾安县余字乡张字村的宁一采摘园,阵阵草莓清香扑面而来,温室大棚的草莓迎来丰收季。不少市民慕名而来,体验采摘乐趣。这里的草莓除了满足游客采摘,还有一部分T80文化国际街区周日闲逛,原本在下马坊博爱园这边逛,走了一条平时不走的小路,直接走过去才发现了这个地方,人很少,看了介绍才知道这个地方原来是中华民国在1934年建造的中央政治学院分院,1949年改在这里,读懂超级网红的前世今生丨寻梦手记寻梦目的地威海市乳山市乳山牡蛎欢乐城景点特色牡蛎文化渔家文化老物件海鲜美食推荐打卡点牡蛎文化博物馆牡蛎文化园交通攻略自驾乘坐乳山201路K201路到华隆商厦下车,剩余70
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网