天天看點

Android 記憶體溢出問題分析。

android雖然會自動管理記憶體,java也有garbage collection (gc )記憶體回收機制。

但是如果程式在一次操作中打開幾個m的檔案,那麼通常會出現下面的錯誤資訊。

02-04 21:46:08.703: error/dalvikvm-heap(2429): 1920000-byte external allocation too large for this process.

02-04 21:52:28.463: error/androidruntime(2429): java.lang.outofmemoryerror: bitmap size exceeds vm budget

移動終端因為記憶體有限,往往圖檔處理經常出現上述的錯誤。

解決方法:

1.明确調用system.gc();

   這種記憶體回收會有一定的作用,但是請不要太期待。

2.圖檔處理完成後回收記憶體。

  請在調用bitmap進行圖檔處理後進行記憶體回收。

  bitmap.recycle();

  這樣會把剛剛用過的圖檔占用的記憶體釋放。

3.圖檔處理時指定大小。

  下面這個方法處理幾個m的圖檔時是必須的。

view plaincopy to clipboardprint?

bitmap getbitpmap(){  

parcelfiledescriptor pfd;  

try{  

    pfd = mcon.getcontentresolver().openfiledescriptor(uri, "r");  

}catch (ioexception ex){  

    return null;  

}  

java.io.filedescriptor fd = pfd.getfiledescriptor();  

bitmapfactory.options options = new bitmapfactory.options();  

    //先指定原始大小   

options.insamplesize = 1;  

    //隻進行大小判斷   

    options.injustdecodebounds = true;  

    //調用此方法得到options得到圖檔的大小   

    bitmapfactory.decodefiledescriptor(fd, null, options);  

    //我們的目标是在800pixel的畫面上顯示。   

    //是以需要調用computesamplesize得到圖檔縮放的比例   

    options.insamplesize = computesamplesize(options, 800);  

    //ok,我們得到了縮放的比例,現在開始正式讀入bitmap資料   

    options.injustdecodebounds = false;  

    options.indither = false;  

    options.inpreferredconfig = bitmap.config.argb_8888;  

    //根據options參數,減少所需要的記憶體   

    bitmap sourcebitmap = bitmapfactory.decodefiledescriptor(fd, null, options);  

    return sourcebitmap;  

//這個函數會對圖檔的大小進行判斷,并得到合适的縮放比例,比如2即1/2,3即1/3   

static int computesamplesize(bitmapfactory.options options, int target) {  

    int w = options.outwidth;  

    int h = options.outheight;  

    int candidatew = w / target;  

    int candidateh = h / target;  

    int candidate = math.max(candidatew, candidateh);  

    if (candidate == 0)  

        return 1;  

    if (candidate > 1) {  

        if ((w > target) && (w / candidate) < target)  

            candidate -= 1;  

    }  

        if ((h > target) && (h / candidate) < target)  

    if (verbose)  

        log.v(tag, "for w/h " + w + "/" + h + " returning " + candidate + "(" + (w/candidate) + " / " + (h/candidate));  

    return candidate;  

繼續閱讀