什么是OOM坡锡?如何解決OOM問題!

1蓬网、什么是OOM?
程序申請內(nèi)存過大鹉勒,虛擬機無法滿足我們帆锋,然后自殺了。這個現(xiàn)象通常出現(xiàn)在大圖片的APP開發(fā)贸弥,或者需要用到很多圖片的時候窟坐。通俗來講就是我們的APP需要申請一塊內(nèi)存來存放圖片的時候,系統(tǒng)認為我們的程序需要的內(nèi)存過大绵疲,及時系統(tǒng)有充分的內(nèi)存哲鸳,比如1G,但是系統(tǒng)也不會分配給我們的APP盔憨,故而拋出OOM異常徙菠,程序沒有捕捉異常,故而彈窗崩潰了
2郁岩、為什么會有OOM婿奔?
因為Android系統(tǒng)的APP每個進程或者虛擬機有最大內(nèi)存限制,一旦超過這個限制系統(tǒng)就會拋出OOM錯誤问慎。跟手機剩余內(nèi)存是否充足沒有多少關系萍摊。
3、為什么Android會有APP的內(nèi)存限制
(1)要開發(fā)者使用內(nèi)存更加合理如叼。限制每個應用可用內(nèi)存上限冰木,避免惡意程序或單個程序使用過多內(nèi)存導致其他程序的不可運行。有了限制笼恰,開發(fā)者就必須合理使用資源踊沸,優(yōu)化資源使用
(2)屏幕顯示內(nèi)容有限,內(nèi)存足夠即可社证。即使有萬千圖片千萬數(shù)據(jù)需要使用到逼龟,但在特定時刻需要展示給用戶看的總是有限的,因為屏幕顯示就那么大追葡,上面可以放的信息就是很有限的腺律。大部分信息都是處于準備顯示狀態(tài),所以沒必要給予太多heap內(nèi)存宜肉。必須一個ListView顯示圖片疾渣,打個比方這個ListView含有500個item,但是屏幕顯示最多有10調(diào)item顯示崖飘,其余數(shù)據(jù)是處于準備顯示狀態(tài)榴捡。
(3)Android多個虛擬機Davlik的限制需要。android設備上的APP運行朱浴,每打開一個應用就會打開至少一個獨立虛擬機吊圾。這樣可以避免系統(tǒng)崩潰达椰,但代價是浪費更多內(nèi)存。
4项乒、有GC自動回收資源啰劲,為什么還會有OOM?
Android的GC會按照特定的算法來回收不使用的資源檀何,但是gc一般回收的是無主的對象內(nèi)存或者軟引用資源蝇裤。
使用軟引用的圖片資源在一定程度上可以避免OOM。
ps:不用的對象設置為null频鉴,是一個好習慣栓辜。不過更好的方法是,不用的圖片直接recycle垛孔。因為有時候通過設置null讓gc來回收還是來不及藕甩。
5、怎么來避免OOM產(chǎn)生呢周荐?
簡單通過SoftReference引用方式管理圖片資源
建一個SoftReference的hashmap狭莱,使用圖片時,先檢查這個hashmap是否有softreference概作,softreference的圖片是否為空腋妙,如果為空將圖片加載到softreference并加入haspmap。
代碼如下:

import java.io.InputStream;  
import java.lang.ref.SoftReference;  
import java.net.HttpURLConnection;  
import java.net.URL;  
import java.net.URLConnection;  
import java.util.HashMap;  
import android.content.Context;  
import android.graphics.Bitmap;  
import android.graphics.BitmapFactory;  
import android.os.Handler;  
import android.os.Handler.Callback;  
import android.os.Message;  
import android.widget.ImageView;  
  
  
/** 
 * 功能說明:異步加載圖片 
 * 
 */  
  
public class AsyncImageLoaderCore {  
    public Context context; // 做本地緩存時會用到  
    public HashMap<String, SoftReference<Bitmap>> imageCache;// 軟引用集合  
     
    public AsyncImageLoaderCore(Context context) {  
        this.context = context;  
        this.imageCache = new HashMap<String, SoftReference<Bitmap>>();  
    }  
  
  
    public Bitmap loadBitmap(final String imageUrl, final ImageView imageView, final ImageCallback imageCallback) {  
        if (imageCache.containsKey(imageUrl)) {  
            SoftReference<Bitmap> softReference = imageCache.get(imageUrl);  
            if (softReference.get() != null)  
                return softReference.get();  
        }  
          
        final Handler handler = new Handler(new Callback() {  
            @Override  
            public boolean handleMessage(Message msg) {  
                imageCallback.imageLoaded((Bitmap) msg.obj, imageView, imageUrl);  
                return false;  
            }  
        });  
          
        new Thread() {  
            @Override  
            public void run() {  
                Bitmap bitmap = null;  
                try {  
                    bitmap = getHttpBitmap(imageUrl);  
                } catch (Exception e) {  
                    e.printStackTrace();  
                    return;  
                }  
                  
                if (null != bitmap) {  
                    imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));  
                    handler.sendMessage(handler.obtainMessage(0, bitmap));  
                }  
            }  
        }.start();  
        return null;  
    }  
    private final int MAX_PIC_LENGTH = 200000;// 最大字節(jié)長度限制[可調(diào),最好不要超過200000]  
    private final int SAMPLE_SIZE = 14;// 裁剪圖片比列(1/14)[可調(diào)]  
    /** 
     * 獲取網(wǎng)絡圖片 
     */  
    private Bitmap getHttpBitmap(String imgUrl) throws Exception {  
        URL htmlUrl = new URL(imgUrl);  
        URLConnection connection = htmlUrl.openConnection();  
        HttpURLConnection conn = (HttpURLConnection) connection;  
        if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {  
            InputStream inputStream = conn.getInputStream();  
            byte[] bytes = changeToBytes(inputStream);  
            if (bytes.length < MAX_PIC_LENGTH) {  
                return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);  
            } else if (bytes.length < MAX_PIC_LENGTH * SAMPLE_SIZE) {  
                BitmapFactory.Options options = new BitmapFactory.Options();  
                options.inJustDecodeBounds = false;  
                options.inSampleSize = SAMPLE_SIZE;  
                return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);  
            }  
        }  
        return null;  
    }  
  
  
    /** 
     * 將流轉換成字節(jié)數(shù)組 
     */  
  
    public byte[] changeToBytes(InputStream inputStream) throws Exception  
    {  
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();  
        byte[] buffer = new byte[1024];// 每次讀取的字節(jié)長度  
        int len = 0;  
        while ((len = inputStream.read(buffer)) != -1)  
        {  
            outputStream.write(buffer, 0, len);  
        }  
        inputStream.close();  
        return outputStream.toByteArray();  
    }  
    /** 
     * 異步加載資源回調(diào)接口 
     */  
    public interface ImageCallback {  
        public void imageLoaded(Bitmap bitmap, ImageView imageView, String imageUrl);  
    }  
}  ```
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末讯榕,一起剝皮案震驚了整個濱河市辉阶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瘩扼,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垃僚,死亡現(xiàn)場離奇詭異集绰,居然都是意外死亡,警方通過查閱死者的電腦和手機谆棺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門栽燕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人改淑,你說我怎么就攤上這事碍岔。” “怎么了朵夏?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵蔼啦,是天一觀的道長。 經(jīng)常有香客問我仰猖,道長捏肢,這世上最難降的妖魔是什么奈籽? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮鸵赫,結果婚禮上衣屏,老公的妹妹穿的比我還像新娘。我一直安慰自己辩棒,他們只是感情好狼忱,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著一睁,像睡著了一般钻弄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上卖局,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天斧蜕,我揣著相機與錄音,去河邊找鬼砚偶。 笑死批销,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的染坯。 我是一名探鬼主播均芽,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼单鹿!你這毒婦竟也來了掀宋?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤仲锄,失蹤者是張志新(化名)和其女友劉穎劲妙,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體儒喊,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡镣奋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了怀愧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侨颈。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖芯义,靈堂內(nèi)的尸體忽然破棺而出哈垢,到底是詐尸還是另有隱情,我是刑警寧澤扛拨,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布耘分,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏陶贼。R本人自食惡果不足惜啤贩,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拜秧。 院中可真熱鬧痹屹,春花似錦、人聲如沸枉氮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽聊替。三九已至楼肪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惹悄,已是汗流浹背春叫。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泣港,地道東北人暂殖。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像当纱,于是被迫代替她去往敵國和親呛每。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

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