Android 記憶體溢出管理與測試

來源:互聯網
上載者:User

標籤:android   des   style   blog   http   java   color   使用   

今天發現正在做的項目,時不時的會報錯:dalvikvm heap out of memory on a 7458832-byte allocation (堆分配的記憶體溢出)

為什麼會記憶體溢出呢?我以前從未遇見這種情況。後來在網上查了查資料,還是挺多的。

怎麼說呢?因為Android開發基本上是以java語言為基礎,那麼程式是在java虛擬機器上啟動並執行。而虛擬機器不允許單個程式中的Bitmap佔用超過8M的記憶體,從報錯的日誌可以看出:7458832-byte大約就是7M多的樣子,基本吻合上述資料。在我的項目中大量的使用到了各種圖片,因此是因為圖片導致記憶體溢出的的可能性很高。

那麼,下面就提供一下解決方案:

 

第一種方案:

Android堆記憶體也可自己定義大小 和 最佳化Dalvik虛擬機器的堆記憶體配置(LZ沒試過,不過網上很多人都說可行)。

強制定義自己軟體的對記憶體大小,我們使用Dalvik提供的 dalvik.system.VMRuntime類來設定最小堆記憶體為例:

private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //設定最小heap記憶體為6MB大小。當然對於記憶體吃緊來說還可以通過手動幹涉GC去處理

第二種方案:

手動的回收記憶體。

範例程式碼如下:bit為Bitmap對象

if (bit != null && !bit.isRecycled()) {                    bit.recycle();                    bit = null;                }
System.gc();

bitmap.recycle()方法用於回收該bitmap所佔用的記憶體,用System.gc()調用一下系統的記憶體回收行程。

需要注意的是:回收記憶體要及時,比如說SurfaceView,就應該在onSurfaceDestroyed這個方法中回收。如果Activity使用了bitmap,就可以在onStop或者onDestroy方法中回收等等。

我首先就是用的這種方法,修改後發現bug出現的頻率減小了,但仍然存在。

第三種方案:

既然是圖的問題,那就從圖片下手。就是使圖片體積大小變小。

這也分為兩個方面:

1、解析度不變,圖片大小減小2、解析度改變,圖片減小。(用PS都很容易的)

需要注意的是:不要減小得太小而影響了人眼看上去的美感。

以上三種方案,後兩種較簡單且常用。

 

另外,因為是Android的圖片導致的記憶體問題,那麼就總結了一下與圖片相關的方法的效能,結果很有收穫啊……(不看不知道,一看嚇一跳)

測試的環境為:筆記本i3處理器,64位win7系統,測試手機為小米2S,測試圖片大小為500KB

比較Drawable與Bitmap佔用記憶體大小

比較BitmapFactory類的decodeResource方法與decodeStream方法的效率

以及最佳化後的BitmapFactory類的decodeResource方法。

下面貼上代碼與運行圖:(每次請只運行一個方法,隱藏另外的三種方法)

public class MainActivity extends Activity {    int number = 1000;    Drawable[] array;    Bitmap bitmap[];    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);         testDrawable();        // testBitmap_decodeResource();        // testBitmap_decodeStream();        //testnewBitmap_decodeResource();    }    /**     * 最佳化後的BitmapFactory類的decodeResource方法     */    private void testnewBitmap_decodeResource() {        bitmap = new Bitmap[number];        for (int i = 0; i < number; i++) {            Log.i("", "測試第" + (i + 1) + "張圖片");            //壓縮,用於節省BITMAP記憶體空間--解決BUG的關鍵步驟             BitmapFactory.Options opts = new BitmapFactory.Options();            opts.inSampleSize = 2;//這個的值壓縮的倍數(2的整數倍),數值越小,壓縮率越小,圖片越清晰             //返回原圖解碼之後的bitmap對象            bitmap[i] = BitmapFactory.decodeResource(getResources(),                    R.drawable.begin_background, opts);        }    }    /**     * BitmapFactory類的decodeStream方法     */    private void testBitmap_decodeStream() {        bitmap = new Bitmap[number];        for (int i = 0; i < number; i++) {            Log.i("", "測試第" + (i + 1) + "張圖片");            bitmap[i] = BitmapFactory.decodeStream(getResources()                    .openRawResource(R.drawable.begin_background));// 這裡換了方法        }    }    /**     * BitmapFactory類的decodeResource方法     */    private void testBitmap_decodeResource() {        bitmap = new Bitmap[number];        for (int i = 0; i < number; i++) {            Log.d("", "測試第" + (i + 1) + "張圖片");            bitmap[i] = BitmapFactory.decodeResource(getResources(),                    R.drawable.begin_background);        }    }    /**     * Drawable的使用     */    private void testDrawable() {        array = new BitmapDrawable[number];        for (int i = 0; i < number; i++) {            Log.w("", "測試第" + (i + 1) + "張圖片");            array[i] = getResources().getDrawable(R.drawable.begin_background);        }    }}

首先貼出   Drawable的使用   的運行結果:(順利測試完1000張圖片)

BitmapFactory類的decodeResource方法運行結果:(居然只有11張)

運行最佳化後的BitmapFactory類的decodeResource方法:(最佳化後可達到46張,且opts.inSampleSize = n;N的參數設定得越大可達到的數量越多,但損失了圖片品質)

BitmapFactory類的decodeStream方法:(可達22張圖片)

這下,相信大家對Android中與圖片相關的這幾種方法的效能有直觀的認識了吧。其實,在測試時除了看到數量外,還可以看到已耗用時間上的差距。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.