什么是OOM
- 當(dāng)前占用內(nèi)存加上我們申請(qǐng)的內(nèi)存資源超過(guò)了Dalvik虛擬機(jī)的最大內(nèi)存限制就會(huì)拋出Out of memory異常。
一些容易混淆的概念
- 內(nèi)存溢出
- 內(nèi)存泄露是指你的應(yīng)用使用資源之后沒(méi)有及時(shí)釋放,導(dǎo)致應(yīng)用內(nèi)存中持有了不需要的資源,這是一種狀態(tài)描述。
- 內(nèi)存泄漏
- 而內(nèi)存溢出是指你的應(yīng)用的內(nèi)存已經(jīng)不能滿足正常使用了,堆棧已經(jīng)達(dá)到系統(tǒng)設(shè)置的最大值,進(jìn)而導(dǎo)致崩潰,這事一種結(jié)果描述。
- 而且通常都是由于內(nèi)存泄露導(dǎo)致堆棧內(nèi)存不斷增大,從而引發(fā)內(nèi)存溢出。
- 內(nèi)存抖動(dòng)
- 內(nèi)存抖動(dòng)是指在短時(shí)間內(nèi)有大量的對(duì)象被創(chuàng)建或者被回收的現(xiàn)象,內(nèi)存抖動(dòng)出現(xiàn)原因主要是頻繁(很重要)在循環(huán)里創(chuàng)建對(duì)象(導(dǎo)致大量對(duì)象在短時(shí)間內(nèi)被創(chuàng)建,由于新對(duì)象是要占用內(nèi)存空間的而且是頻繁,如果一次或者兩次在循環(huán)里創(chuàng)建對(duì)象對(duì)內(nèi)存影響不大,不會(huì)造成嚴(yán)重內(nèi)存抖動(dòng)這樣可以接受也不可避免,頻繁的話就很內(nèi)存抖動(dòng)很嚴(yán)重),內(nèi)存抖動(dòng)的影響是如果抖動(dòng)很頻繁,會(huì)導(dǎo)致垃圾回收機(jī)制頻繁運(yùn)行(短時(shí)間內(nèi)產(chǎn)生大量對(duì)象,需要大量?jī)?nèi)存,而且還是頻繁抖動(dòng),就可能會(huì)需要回收內(nèi)存以用于產(chǎn)生對(duì)象,垃圾回收機(jī)制就自然會(huì)頻繁運(yùn)行了)。綜上就是頻繁內(nèi)存抖動(dòng)會(huì)導(dǎo)致垃圾回收頻繁運(yùn)行。
App運(yùn)行時(shí)發(fā)生OOM的原因
App運(yùn)行時(shí)發(fā)生OOM的原因你知道幾種?應(yīng)該如何避免?
- 1.資源對(duì)象用完沒(méi)有關(guān)閉,造成內(nèi)存泄漏。避免:對(duì)于資源性對(duì)象,在try catch finally中將資源對(duì)象放在finally中進(jìn)行回收處理,可以有效避免OOM。資源性對(duì)象例如:
- 1-1:Cursor(使用Curosr.close())
- 1-2: 沒(méi)有關(guān)閉InputStream/OutputStream
- 1-3:使用完registerReceiver后沒(méi)有調(diào)用unregisterReceiver
- 1-4: Bitmap使用完后沒(méi)有調(diào)用recycle
- 2.作用域不一樣,導(dǎo)致對(duì)象不能被垃圾回收器回收
- 2-1:非靜態(tài)內(nèi)部類隱式持有外部類的引用
- 2-2:Context泄漏:
- 2-2-1:不要保留Context-Activity長(zhǎng)時(shí)間的引用(使用Context-Activity時(shí)必須確保和Activity一樣的生命周期)
- 2-2-2:使用Context-Application代替Context-Activity。
- 2-2-3: 如果你不想控制內(nèi)部類的生命周期,應(yīng)該避免在Activity中使用非靜態(tài)內(nèi)部類,應(yīng)該使用靜態(tài)內(nèi)部類,并且在其中創(chuàng)建一個(gè)Activity的弱引用(WeakRefrener)。
- 2-3:Thread中引用其他對(duì)象也容易造成內(nèi)存泄漏。
- 2-4:OnReceive方法里執(zhí)行了太多操作。
- 3.內(nèi)存壓力過(guò)大
- 3-1:圖片資源加載過(guò)多,超出內(nèi)存使用空間,例如Bitmap。
- 3-2: 重復(fù)創(chuàng)建View,listview應(yīng)該復(fù)用convertview和viewholder。
避免內(nèi)存泄漏:
- 1:使用緩存技術(shù),如LruCache、DisLruCache、對(duì)象重復(fù)并且頻繁調(diào)用可以考慮對(duì)象池。
- 2:對(duì)于生命周期不一樣的對(duì)象,可以采用軟引用或弱引用(SoftRefrener,WeakRefrener)。
- 3: 對(duì)于資源對(duì)象用完后在finally中強(qiáng)制關(guān)閉。
- 4:內(nèi)存壓力過(guò)大,就要用統(tǒng)一的內(nèi)存管理。
- 5: 有關(guān)Bitmap ,主要涉及: 圖片加載方式,及時(shí)釋放內(nèi)存,圖片壓縮,inBitmap屬性,捕獲異常。
- 6: listView: convertView/LRU ,避免在OnDraw方法中執(zhí)行對(duì)象的創(chuàng)建。