Android性能優(yōu)化---內(nèi)存優(yōu)化

讀書筆記:Android應(yīng)用性能優(yōu)化最佳實(shí)踐

一止后、影響卡頓的基本原因

1.繪制任務(wù)太重
2.主線程任務(wù)耗時(shí)太長

二抄课、頁面繪制的流程

CPU準(zhǔn)備數(shù)據(jù)---GPU從緩存列表獲取數(shù)據(jù)----Display顯示數(shù)據(jù)

三窑睁、性能優(yōu)化檢測工具

1.Profile GPU rendering :GPU呈現(xiàn)模式分析

或是使用dumpsys命令更直觀的查看繪制的耗時(shí)
adb shell dumpsys gfxinfo com.efrobot.robot.video

2.Systrace UI
分析UI的性能
參考Systrace
3.TraceView
分析函數(shù)的執(zhí)行過程和耗時(shí)時(shí)間
參考TraceView
4.Hierarchy Viewer
查看Layout的嵌套以及繪制的時(shí)間
5.Java Heap
查看內(nèi)存分配
6.Allocation Trace
觀察一段時(shí)間內(nèi),內(nèi)存分配的次數(shù)和類
7.Show GPU Overdraw
手機(jī)檢查過渡繪制

四、布局優(yōu)化

1.減少層級(jí)
合理的使用布局

RelativeLayout:繪制層級(jí)少拴泌,可以替代LinearLayout多嵌套才能實(shí)現(xiàn)的效果,但是性能差惊橱,因?yàn)橐獧M向蚪腐,縱向測量兩次。
LinearLayout:測量少税朴,但是實(shí)現(xiàn)復(fù)雜布局需要多次嵌套回季。

使用Merge標(biāo)簽減少布局,優(yōu)化布局層級(jí)

1.在Activity整體的布局中正林,跟布局元素要是FrameLayout
2.必須為該布局指定一個(gè)ViewGroup泡一,并且attachToRoot為true
3.不能在ViewStub中使用

使用ViewStub提高顯示速度:當(dāng)布局在加載時(shí)不是所有所有元素都要顯示時(shí),可以使用

ViewStub只能加載布局
加載一次后就不能再對(duì)布局做操作

避免默認(rèn)主題的背景:使用activity的自動(dòng)主題時(shí)會(huì)有一個(gè)默認(rèn)背景觅廓,由DecorView持有

this.getWindow().setBackground(null)

五鼻忠、啟動(dòng)耗時(shí)優(yōu)化

1.獲取activity的啟動(dòng)時(shí)間
使用ADB命令

adb shell am start -W [packageName]/packageName.ActivityName

2.代碼打點(diǎn)

Application,Activity聲明周期打點(diǎn)
數(shù)據(jù)庫操作打點(diǎn)
其他的耗時(shí)業(yè)務(wù)打點(diǎn)
3.優(yōu)化的方向
1.UI布局:檢查是否過渡繪制杈绸,布局嵌套帖蔓,掉幀嚴(yán)重
2.邏輯優(yōu)化:異步加載,延期加載瞳脓,分布加載
3.避免后臺(tái)線程操作造成頻繁的GC:例如在ListView滑動(dòng)時(shí)禁止使用后臺(tái)線程下載圖片
4.使用TraceView查看updateDisplayListIfDirty方法塑娇,最后畫面刷新到屏幕上需要調(diào)用DisplayList方法

六、動(dòng)畫優(yōu)化

1.使用屬性動(dòng)畫優(yōu)化刷新率劫侧,盡量避免補(bǔ)間動(dòng)畫
2.在動(dòng)畫上使用硬件加速(慎重使用 )

七埋酬、內(nèi)存優(yōu)化

GC的過程中,任何工作線程都將停止,GC的時(shí)間越長奇瘦,卡頓越明顯棘催,還會(huì)造成OOM問題。
1.對(duì)象的幾個(gè)階段:創(chuàng)建---使用---不可達(dá)---不可見--不可達(dá)---收集---回收
不可見:無法找到引用該對(duì)象的引用關(guān)系耳标,但可能被靜態(tài)變量醇坝,JNI層強(qiáng)引用,無法回收

2.內(nèi)存分配
ART和Dalvik虛擬機(jī)在內(nèi)存分配
LinearAlloc:存儲(chǔ)虛擬機(jī)中的類以及永久數(shù)據(jù)次坡,一塊只讀的空間
Zygote Space:
Allocation Space:分配內(nèi)存區(qū)域
Image Space:負(fù)責(zé)分配預(yù)加載類
Large Space:負(fù)責(zé)分配大對(duì)象地址

3.內(nèi)存回收機(jī)制
年輕區(qū)---老年區(qū)--持久區(qū)

新生對(duì)象首先在eden區(qū)創(chuàng)建呼猪,當(dāng)eden區(qū)滿時(shí),會(huì)將存活的內(nèi)存放到s0區(qū)砸琅,s0區(qū)滿時(shí)宋距,會(huì)將此時(shí)還活著的對(duì)象移動(dòng)到s1區(qū)域s0清零,當(dāng)s1區(qū)域也滿時(shí)症脂,會(huì)復(fù)制s1中的數(shù)據(jù)到s0谚赎,反復(fù)執(zhí)行幾次后仍然活著的對(duì)象會(huì)放到老年代。在老年代經(jīng)理過幾次gc仍然存活的對(duì)象會(huì)被移動(dòng)到 持久區(qū)中诱篷。

4.使用Allocation Tracker查看內(nèi)存分配
Allocation Tracker可以查看一段時(shí)間內(nèi)內(nèi)存分配的次數(shù)壶唤,和分配的大小,詳見參考文章
https://blog.csdn.net/itfootball/article/details/48735041
https://blog.csdn.net/itfootball/article/details/48750849

5.分析Hprof文件
通過AndroidStudio生成Hprof文件棕所,觀察視圖闸盔,使用Merge Shortest Path to GC roots,查看合并節(jié)點(diǎn)后,是否還有可達(dá)到該對(duì)象的路徑琳省,如果有那么表示該對(duì)象無法回收迎吵,可能出現(xiàn)內(nèi)存泄漏

八、引用區(qū)分

1.強(qiáng)引用:不會(huì)被GC回收针贬,回收不了會(huì)OOM
2.軟引用:在虛擬機(jī)報(bào)告內(nèi)存溢出前击费,如果內(nèi)存不足回收對(duì)象
3.弱引用:GC就回收

九、內(nèi)存優(yōu)化

1.在1000數(shù)量級(jí)以內(nèi)使用ArrayMap
2.使用基本類型加@IntDef和@StringDef類代替枚舉
3.使用LruCache管理圖片
4.圖片內(nèi)存優(yōu)化

在android上加載圖片桦他,需要將圖片加載成位圖(由多個(gè)像素點(diǎn)組成的圖)荡灾,再解鎖成位圖后,內(nèi)存=寬x高x單位內(nèi)像素瞬铸。圖片被處理32bit/像素的位圖(ARGB_8888)批幌,紅,綠嗓节,藍(lán)荧缘,透明各占8bit。即使圖片不存在透明區(qū)也會(huì)分配8bit的透明區(qū)拦宣。

5.可以修改圖片的格式
RGB_565(16bit)截粗,ARGB_4444(16bit)信姓,ALPHA_8(8bit)。小屏手機(jī)且對(duì)圖像要求不高可以使用rgb绸罗,圓角頭像可以使用ARGB4444,.

BitmapFactory.Options option =new BitmapFactory.Options()
options.inPreferredConfig=Bitmap.Config.RGB_565
BitmapFactory.decodeStream(is,null,options)

6.inSampleSize,inDensity,inTargetDensity:
如果圖片在內(nèi)存中的大小遠(yuǎn)遠(yuǎn)大于使用大小可以使用inSampleSize來壓縮圖片意推,inScaled 會(huì)按照現(xiàn)有密度重新劃分目標(biāo)密度,重新計(jì)算圖片大小.

使用inSampleSize壓縮圖片珊蟀,
BitmapFactory.Options option =new BitmapFactory.Options()
option.inJustDecodeBounds=true;
BitmapFactory.decodeStream(is,null,options)
options.inScaled=true菊值;
options.inDensity=options.outWidth;0
options.inSampleSize=40
options.inTargetDensity=dstWidth*options.inSampleSize;
options.inJustDecode=false;

6.使用三級(jí)緩存對(duì)大量圖片進(jìn)行優(yōu)化

內(nèi)存--本地--網(wǎng)絡(luò)

1.使用LruCache
將最近使用過對(duì)象的強(qiáng)引用放到LinkedHashMap中,將最近最少使用的對(duì)象移除育灸。
2.內(nèi)存復(fù)用
使用Bitmap的options對(duì)象的inBitmap參數(shù):在LruCache移除圖片后腻窒,可以將移除的圖片加入到復(fù)用集合中,當(dāng)需要加載新的圖片時(shí)磅崭,先查找內(nèi)存儿子,再查找復(fù)用集合中是否有符合的圖片。

Bitmap inBitmap=cache.getBitmapFromReusableSet()
if(inBitmap!=null){
  options.inBitmap=inBitmap砸喻;
}

3.使用磁盤緩存
使用DiskLruCache

十柔逼、String的優(yōu)化

參考:http://www.androidchina.net/5940.html
String的值是存儲(chǔ)在常量池(在編譯時(shí)期將值保存在.class文件中)中的,一旦創(chuàng)建將不可以修改割岛。

十一卒落、存儲(chǔ)優(yōu)化

1.SharePreference優(yōu)化
Editor的commit是同步寫入,apply是異步寫入蜂桶。在不需要返回值的情況下,使用apply能夠極大的提升性能
SharePreference的的put和getEditor()會(huì)鎖定Editor對(duì)象也切,所以大量寫入SharePreference對(duì)象最后提前獲得一個(gè)Editor對(duì)象扑媚,并且通過標(biāo)志位判斷是否需要讀寫。

if(開關(guān)沒有改變&&沒有發(fā)生變化){
}

2.數(shù)據(jù)庫優(yōu)化
1.使用SQLiteStatement來執(zhí)行插入操作

SQLiteStatement statement=getSqliteDB().compileStatement(STR_INSERT_STATEMENT_CONTACTS)雷恃;
statement.clearBindings();
statement.bind..();

2.更好的方法是使用事物
在數(shù)據(jù)庫插入代碼中疆股,如果沒有顯示的使用事物,系統(tǒng)會(huì)自動(dòng)創(chuàng)建一個(gè)事物倒槐,如果插入的頻繁就會(huì)頻繁的創(chuàng)建事物旬痹。所以顯示的創(chuàng)建一次事物,可以提高效率讨越。

getSqliteDB().beginTranscation();
for(){
   getSqliteDB().insert(...)
}
getSqliteDB().setTranscationSuccessful();
getSqliteDB().endTranscation();

十二两残、Service的包活

1.守護(hù)進(jìn)程
2.網(wǎng)絡(luò)連接保持和Service的交互
3.使用SyncAdapter:是一個(gè)系統(tǒng)服務(wù),通過系統(tǒng)的定時(shí)器更新數(shù)據(jù)到ContentProvider,工作在一個(gè)獨(dú)立的進(jìn)程把跨,屬于核心進(jìn)程級(jí)別人弓。使用它本身也會(huì)提高進(jìn)程級(jí)別

十三、耗電優(yōu)化

1.android5.0提供了Battery Historian查看電量使用
2.使用命令

//獲取電量權(quán)限着逐,并重置電量日志
adb shell dumpsys batterystats --enable full-wake-history
shell dumpsys batterystats --reset
//保存數(shù)據(jù)
adb bugreport >bugreport.txt

將文件轉(zhuǎn)化為html崔赌,需要下載battery-historian

python historian.py -a bugreport.txt >battery.html

3.注意消耗:使用WakeLock一定要記得釋放
4.使用JobScheduler執(zhí)行部分任務(wù)

重要不緊急的任務(wù)
耗電量較大的任務(wù)
可以批量執(zhí)行的任務(wù)

十二意蛀、代碼審查

1.單一職責(zé),一個(gè)模塊只負(fù)責(zé)一件事
2.對(duì)象的可擴(kuò)展開放健芭,可修改關(guān)閉
3.代碼復(fù)用要提取一個(gè)公共類
4.是否有更好的實(shí)現(xiàn)
5.錯(cuò)誤是否被更好的處理县钥,而不是粗略屏蔽
6.效率:選用的算法是否更有效率

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市慈迈,隨后出現(xiàn)的幾起案子若贮,更是在濱河造成了極大的恐慌,老刑警劉巖吩翻,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兜看,死亡現(xiàn)場離奇詭異,居然都是意外死亡狭瞎,警方通過查閱死者的電腦和手機(jī)细移,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來熊锭,“玉大人弧轧,你說我怎么就攤上這事⊥胍螅” “怎么了精绎?”我有些...
    開封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锌妻。 經(jīng)常有香客問我代乃,道長,這世上最難降的妖魔是什么仿粹? 我笑而不...
    開封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任搁吓,我火速辦了婚禮,結(jié)果婚禮上吭历,老公的妹妹穿的比我還像新娘堕仔。我一直安慰自己,他們只是感情好晌区,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開白布摩骨。 她就那樣靜靜地躺著,像睡著了一般朗若。 火紅的嫁衣襯著肌膚如雪恼五。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天哭懈,我揣著相機(jī)與錄音唤冈,去河邊找鬼。 笑死银伟,一個(gè)胖子當(dāng)著我的面吹牛你虹,可吹牛的內(nèi)容都是我干的绘搞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼傅物,長吁一口氣:“原來是場噩夢啊……” “哼夯辖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起董饰,我...
    開封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蒿褂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后卒暂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啄栓,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年也祠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了昙楚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诈嘿,死狀恐怖堪旧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奖亚,我是刑警寧澤淳梦,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站昔字,受9級(jí)特大地震影響爆袍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜作郭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一陨囊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧所坯,春花似錦、人聲如沸挂捅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闲先。三九已至状土,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伺糠,已是汗流浹背蒙谓。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留训桶,地道東北人累驮。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓酣倾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谤专。 傳聞我的和親對(duì)象是個(gè)殘疾皇子躁锡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容