內(nèi)存泄露
產(chǎn)生的原因:一個(gè)長生命周期的對(duì)象持有一個(gè)短生命周期對(duì)象的引用
通俗講就是該回收的對(duì)象,因?yàn)橐脝栴}沒有被回收脊阴,最終會(huì)產(chǎn)生OOM
內(nèi)存抖動(dòng)
內(nèi)存頻繁的分配與回收披摄,(分配速度大于回收速度時(shí))最終會(huì)產(chǎn)生OOM
使用工具分析內(nèi)存泄露和抖動(dòng)
常用的內(nèi)存分析的工具:
Android Profiler
MAT
DDMS
top/procrank
meinfo
Procstats
Finder-Activity
LeakCanary
LeakInspector
工具很多帅韧,掌握原理方法榨为,工具隨便找兩個(gè)能用就行惨好,這里就不多做介紹了。
優(yōu)化內(nèi)存的良好編碼習(xí)慣
1.不要使用比需求更占空間的基本數(shù)據(jù)類型
2.循環(huán)盡量用foreach,少用iterator, 自動(dòng)裝箱盡量少用
3.數(shù)據(jù)結(jié)構(gòu)與算法的解度處理
數(shù)組随闺,鏈表日川,棧,樹矩乐,圖龄句。。散罕。分歇。。欧漱。
數(shù)據(jù)量千級(jí)以內(nèi)可以使用 Sparse數(shù)組(key為整數(shù))卿樱,ArrayMap(key為對(duì)象),性能不如HashMap但節(jié)約內(nèi)存
4.枚舉優(yōu)化
每一個(gè)枚舉值都是一個(gè)單例對(duì)象,在使用它時(shí)會(huì)增加額外的內(nèi)存消耗,所以枚舉相比與 Integer 和 String 會(huì)占用更多的內(nèi)存,較多的使用 Enum 會(huì)增加 DEX 文件的大小,會(huì)造成運(yùn)行時(shí)更多的IO開銷,使我們的應(yīng)用需要更多的空間,特別是分dex多的大型APP硫椰,枚舉的初始化很容易導(dǎo)致ANR
5.static staticfinal的問題:
static會(huì)由編譯器調(diào)用clinit方法進(jìn)行初始化
static final不需要進(jìn)行初始化工作,打包在dex文件中可以直接調(diào)用萨蚕,并不會(huì)在類初始化申請(qǐng)內(nèi)存
所以基本數(shù)據(jù)類型的成員靶草,可以全寫成static final
6.字符串的連接盡量少用加號(hào)(+)
7.重復(fù)申請(qǐng)內(nèi)存的問題
同一個(gè)方法多次調(diào)用,如遞歸函數(shù) 岳遥,回調(diào)函數(shù)中new對(duì)象,讀流直接在循環(huán)中new對(duì)象等
不要在onMeause() onLayout() onDraw() 中去刷新UI(requestLayout)
8.避免GC回收將來要重用的對(duì)象
內(nèi)存設(shè)計(jì)模式對(duì)象池+LRU算法
9.Activity組件泄漏
非業(yè)務(wù)需要不要把a(bǔ)ctivity的上下文做參數(shù)傳遞奕翔,可以傳遞application的上下文
和Activity有關(guān)聯(lián)的對(duì)象寫成static 如private static Button btn; private static Drawable drawable
非靜態(tài)內(nèi)部類和匿名內(nèi)部?jī)?nèi)會(huì)持有activity引用
單例模式持有activity引用
handler.postDelayed()問題如果開啟的線程需要傳入?yún)?shù),用弱引接收可解決問題
handler記得清除removeCallbacksAndMessages(null)
10.盡量使用IntentService,而不是Service