天天看点

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;  

继续阅读