- 內(nèi)存溢出 (OOM)是指程序在申請內(nèi)存時,沒有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory;比如只申請了一個integer,但給它存了long才能存下的數(shù),那就會出現(xiàn)內(nèi)存溢出。
- 內(nèi)存泄露 (memory leak)是指程序在申請內(nèi)存后,無法釋放已申請的內(nèi)存空間,一次內(nèi)存泄露危害可以忽略,但內(nèi)存泄露堆積后果很嚴(yán)重,無論多少內(nèi)存,遲早會被占光。
- 內(nèi)存泄漏最終會導(dǎo)致內(nèi)存溢出。
大部分的OOM都是發(fā)生在圖片加載上的,當(dāng)我們加載大圖時,需要特別注意避免OOM的發(fā)生。
- 處理大圖片時,不管你的手機(jī)內(nèi)存有多大,如果不對圖片進(jìn)行處理,都有可能會發(fā)生內(nèi)存溢出問題。
- 1、在內(nèi)存中壓縮圖片
裝載大圖片時需要對圖片進(jìn)行壓縮,使用等比例壓縮的方法直接在內(nèi)存中處理圖片
Options options = new BitmapFactory.Options();
options.inSampleSize = 5; // 原圖的五分之一,設(shè)置為2則為二分之一
BitmapFactory.decodeFile(myImage.getAbsolutePath(), options);
這樣做要注意的是,圖片質(zhì)量會變差,inSampleSize設(shè)置的值越大,圖片質(zhì)量就越差,不同的手機(jī)廠商縮放的比例可能不同。
- 2、使用完圖片后回收圖片所占內(nèi)存** 由于Android外層是使用java而底層使用的是C語言在里層為圖片對象分配的內(nèi)存空間。 所以我們的外部雖然看起來釋放了,但里層卻并不一定完全釋放了,我們使用完圖片后最好再釋放掉里層的內(nèi)存空間。
if (!bitmapObject.isRecyled()) { // Bitmap對象沒有被回收
bitmapObject.recycle(); // 釋放
System.gc(); // 提醒系統(tǒng)及時回收
}
3、降低要顯示的圖片色彩質(zhì)量
Android中Bitmap有四種圖片色彩模式:
ALPHA_8:每個像素需要占用內(nèi)存中的1byte
RGB_565:每個像素需要占用內(nèi)存中的2byte
ARGB_4444:每個像素需要占用內(nèi)存中的2byte
ARGB_8888:每個像素需要占用內(nèi)存中的4byte
我們創(chuàng)建Bitmap時,默認(rèn)的色彩模式是ARGB_8888的,這種色彩模式是質(zhì)量最高的,當(dāng)然這樣的模式占用的內(nèi)存也最大。
而ARGB_4444每個像素只占用2byte,所以使用ARGB_4444的模式也能降低圖片占用的內(nèi)存大小。4、查詢圖片信息時不把圖片加載到內(nèi)存中
有時候我們?nèi)〉靡粡垐D片,也許只是為了獲得這個圖片的一些信息,比如圖片的width、height等信息,不需要顯示到界面上,這個時候我們可以不把圖片加載到內(nèi)存中。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; // 不把圖片加載到內(nèi)存中
Bitmap btimapObject = BitmapFactory.decodeFile(myImage.getAbsolutePath(), options);
如何避免內(nèi)存泄漏?
1,在 onDestroy()方法中顯示調(diào)用mThread.close();以此來結(jié)束該線程,這就避免了線程的內(nèi)存泄漏問題。
2,使用application context 代替activity context;
3,資源對象沒關(guān)閉造成的內(nèi)存泄漏,如Cursor沒有close掉;
4,Bitmap記得recycle掉;
5,構(gòu)造Adapter時,沒有使用緩存的convertView。