安卓BitmapFactory.decodeStream報(bào)java.lang.OutOfMemoryError內(nèi)存溢出

一丶java.lang.OutOfMemoryError異常常見(jiàn)原因:

1.內(nèi)存中加載的數(shù)據(jù)量過(guò)于龐大,如一次從數(shù)據(jù)庫(kù)取出過(guò)多數(shù)據(jù);
2.集合類中有對(duì)對(duì)象的引用,使用完后未清空,使得JVM不能回收;
3.代碼中存在死循環(huán)或循環(huán)產(chǎn)生過(guò)多重復(fù)的對(duì)象實(shí)體;

二丶BitmapFactory.decodeStream出現(xiàn)OutOfMemoryError異常

  log:java.lang.OutOfMemoryError: Failed to allocate a 4308492 byte allocation with 467872 free bytes and 456KB until OOM

??我以為是我的Bitmap太大了,于是對(duì)Bitmap進(jìn)行一系列優(yōu)化,點(diǎn)擊run,然并卵又TMD出現(xiàn)OutOfMemoryError,還是太年輕啊。

三、解決方法

1.什么是內(nèi)存泄露?
??內(nèi)存泄露指程序中沒(méi)有正確的釋放用完的內(nèi)存空間,導(dǎo)致運(yùn)行異常或錯(cuò)誤
2.AndroidStudio如何檢測(cè)內(nèi)容泄漏
??Tools——Android——Android device monitor


image.png

image.png

image.png

??通過(guò)AndroidStudio的內(nèi)存檢測(cè)工具很清楚的看到內(nèi)存使用情況,經(jīng)測(cè)試一個(gè)幾百k的圖片,使用BitmapFactory.decodeStream()方法卻要試圖分配1M的內(nèi)存
??首先我們知道安卓開(kāi)發(fā)中一般從網(wǎng)絡(luò)獲取圖像,使用BitmapFactory的decodeStream函數(shù)來(lái)獲取到bitmap。Android又在圖像方面面消耗內(nèi)存較多,本文就主要記錄怎樣正確的展現(xiàn)圖像減少對(duì)內(nèi)存的開(kāi)銷,有效的避免oom現(xiàn)象。那我們的內(nèi)存為什么會(huì)被消耗那么多呢?是因?yàn)锽itmapFactory的每個(gè)decode函數(shù)都會(huì)生成一個(gè)bitmap對(duì)象,內(nèi)存就是去bitmap里了,如果圖像過(guò)多就會(huì)出現(xiàn)OutOfMemoryError異常。不多說(shuō),直接上代碼,以下為優(yōu)化方法:

  InputStream bitmapIs = HttpUtils.getStreamFromURL(imageURL);
                Bitmap bitmap = null;
                try {
                     bitmap =getFitSampleBitmap(bitmapIs);
                } catch (Exception e) {
                    e.printStackTrace();
                }
public  static  Bitmap  getFitSampleBitmap(InputStream  inputStream) throws Exception{
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            byte[] bytes = readStream(inputStream);
            BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
            options.inSampleSize = 2;
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
}
    /**
     * 從inputStream中獲取字節(jié)流 數(shù)組大小
     **/
        public static byte[] readStream(InputStream inStream) throws Exception{
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
            }
            outStream.close();
            inStream.close();
            return outStream.toByteArray();
        }

??BitmapFactory提供了BitmapFactory.Option,用于設(shè)置圖像相關(guān)的參數(shù), inJustDecodeBounds :如果設(shè)置為true則表示decode函數(shù)不會(huì)生成bitmap對(duì)象,僅是將圖像相關(guān)的參數(shù)填充到option對(duì)象里,這樣我們就可以在不生成bitmap而獲取到圖像的相關(guān)參數(shù)了。
??inSampleSize:表示對(duì)圖像像素的縮放比例。假設(shè)值為2,表示decode后的圖像的像素為原圖像的1/2。
??在設(shè)置了option的inSampleSize后我們將inJustDecodeBounds設(shè)置為false再次調(diào)用decode函數(shù)時(shí)就能生成bitmap了。
最后為了保險(xiǎn)起見(jiàn)加上如下代碼:

if (bitmap.isRecycled()== false ){
    bitmap.recycle();
}

如果代碼已經(jīng)不再需要使用Bitmap對(duì)象了,手動(dòng)回收。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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