Android中內(nèi)存優(yōu)化簡單總結(jié)

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

內(nèi)存泄漏不一定造成程序的crash,但內(nèi)存溢出肯定會(huì)造成程序的crash,所以我們需要解決的是在程序沒有crash之前的問題
1. 內(nèi)存泄漏: 根本原因是長生命周期的對象持有短生命周期的對象,造成短生命周期對象無法及時(shí)釋放

  1. 內(nèi)存泄漏種類:
  • 靜態(tài)集合類引起內(nèi)存泄漏
    像HashMap、Vector等的使用最容易出現(xiàn)內(nèi)存泄露,這些靜態(tài)變量的生命周期和應(yīng)用程序一致,他們所引用的所有的對象Object也不能被釋放,因?yàn)樗麄円矊⒁恢北籚ector等引用著。
    盡量避免使用 static 成員變量

  • 當(dāng)集合里面的對象屬性被修改后,再調(diào)用remove()方法時(shí)不起作用。
    經(jīng)過測試,當(dāng)set集合的hashcode被修改后,就沒有辦法remove了

  • 監(jiān)聽器沒有remove
    我們經(jīng)常會(huì)跟監(jiān)聽器打交道,通常一個(gè)應(yīng)用當(dāng)中會(huì)用到很多監(jiān)聽器,我們會(huì)調(diào)用一個(gè)控件的諸如addXXXListener()等方法來增加監(jiān)聽器,但是當(dāng)我們不需要的時(shí)候,卻忘記removeXXXListener(),從而增加了內(nèi)存泄漏的機(jī)會(huì),最經(jīng)常的是unregisterrecevier(反注冊廣播)

  • 各種數(shù)據(jù)鏈接沒有關(guān)閉,比如數(shù)據(jù)庫
    比如數(shù)據(jù)庫連接,網(wǎng)絡(luò)連接(socket),io流連接,ContentProvider(內(nèi)容提供者),cursor(游標(biāo))除非其顯式的調(diào)用了其close()方法在finally里面將其連接關(guān)閉,否則是不會(huì)自動(dòng)被GC回收的
    在數(shù)據(jù)連接使用完畢以后一定要進(jìn)行關(guān)閉操作

  • 內(nèi)部類:
    java內(nèi)部類擁有外部類的強(qiáng)引用,比如在new thread中,當(dāng)線程沒有結(jié)束時(shí),activity不會(huì)被回收
    比如context的引用,當(dāng)內(nèi)部類的TextView等等都會(huì)持有上下文的引用
    如果有static drawable就會(huì)導(dǎo)致內(nèi)存無法釋放
    將內(nèi)部類改為靜態(tài)內(nèi)部類,靜態(tài)內(nèi)部類中使用弱引用來引用外部類的成員變量

  • 單例模式
    單例是一個(gè)全局的靜態(tài)對象,當(dāng)持有外部類對象的引用時(shí),此對象無法被釋放,內(nèi)存會(huì)leak
    避免 override finalize() (手動(dòng)開啟GC回收機(jī)制)
    *finalize 方法被執(zhí)行的時(shí)間不確定,不能依賴與它來釋放緊缺的資源。時(shí)間不確定的原因是: 虛擬機(jī)調(diào)用GC的時(shí)間不確定

如何避免00M異常

首先OOM是什么?(內(nèi)存溢出)
當(dāng)程序需要申請一段“大”內(nèi)存,但是虛擬機(jī)沒有辦法及時(shí)的給到,即使做了GC操作以后
這就會(huì)拋出 OutOfMemoryException 也就是OOM

Android的OOM怎么樣?
為了減少單個(gè)APP對整個(gè)系統(tǒng)的影響,android為每個(gè)app設(shè)置了一個(gè)內(nèi)存上限。
HTC M7實(shí)測,192M上限。512M 一般情況下,192M就是上限,但是由于某些特殊情況,android允許使用一個(gè)更大的RAM。

如何避免OOM?
最重要的是肯定是你的程序沒有語法,邏輯錯(cuò)誤導(dǎo)致的OOM,然后使用以下方法盡量減少內(nèi)存消耗在,Android應(yīng)用的開發(fā)中,為了防止內(nèi)存溢出,在處理一些占用內(nèi)存大而且聲明周期較長的對象時(shí)候,可以盡量應(yīng)用軟引用和弱引用技術(shù)。

  • 減少內(nèi)存對象的占用
  1. ArrayMap/SparseArray代替hashmap
  2. 避免在android里面使用Enum
  3. 減少bitmap的內(nèi)存占用
    ? inSampleSize:縮放比例,在把圖片載入內(nèi)存之前,我們需要先計(jì)算出一個(gè)合適的縮放比例,避免不必要的大圖載入。
    ? decode format:解碼格式,選擇ARGB_8888/RBG_565/ARGB_4444/ALPHA_8,存在很大差異。
  4. 減少資源圖片的大小,過大的圖片可以考慮分段加載
  • 內(nèi)存對象的重復(fù)利用
    大多數(shù)對象的復(fù)用,都是利用對象池的技術(shù)。
  1. listview/gridview/recycleview contentview的復(fù)用
  2. inBitmap 屬性對于內(nèi)存對象的復(fù)用ARGB_8888/RBG_565/ARGB_4444/ALPHA_8
    這個(gè)方法在某些條件下非常有用,比如要加載上千張圖片的時(shí)候。
  3. 避免在ondraw方法里面 new對象
  4. StringBuilder 代替+
  5. 使用最近最少使用算法(Lrucache)等算法,利用時(shí)間換空間策略減少內(nèi)存消耗
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容