位图创建时出现Android OutOfMemory错误

时间:2012-01-18 02:41:37

标签: android memory graphics graph bitmap

我收到错误java.lang.OutOfMemoryError: bitmap size exceeds VM budget

为了手动绘制折线图而创建位图时会发生这种情况。

width = display.getWidth() - 10;
height = width * 4 / 5;
Bitmap emptyBmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Bitmap charty = createMyGraphAndStuff(emptyBmap);

看起来分配的总内存大约是700 Kb,这是一个不合理的数量。

我已经看到在从文件创建位图时调用的其他解决方案,但在这里我自己生成一个。如何最小化其内存占用?

这里有一些代码可以让您更好地了解它正在做什么:

public Bitmap DrawTheGraphAndStuff(Bitmap bitmap, String[] scores)
{
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        drawTheGridLines(canvas);                                   

        plotTheDataPoints(canvas ,  scores ,  "the title" , 0 );    

        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
}

5 个答案:

答案 0 :(得分:6)

当OOM发生时,给出一些建议:

1.需要知道oom发生位置,日志信息就足够了

2.大部分时间是位图处理,所以你需要知道有关已用内存的图像:

公式:w * h * every pixel token memory in byte,如果ConfigConfig.ARGB_8888,则每个像素令牌记忆为4bytes,如果是Config.RGB_565,则为{{} 1}}。

3.此外,您需要了解设备中的每个应用程序内存限制:

2bytes

3.如果位图没有再次使用,请尝试 ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); activityManager.getMemoryClass(); //return the memory size limit in MB

4.如果开始位图处理,内存几乎是最大内存限制,所以使用recyle()检查内存使用情况,adb shell dumpsys meminfo $pid也很有用

答案 1 :(得分:1)

如果您的显示宽度为480,则您的位图为470x376。每像素4个字节,即706880字节。使用更少内存的唯一方法是缩小位图。

答案 2 :(得分:1)

基本上回收你的位图,你不应该再遇到这个问题了。使用recycle()。

答案 3 :(得分:1)

这不是一个真正需要解决的问题,这是一个需要解决的设计问题。您不能假设有关可供您使用的堆的任何内容。以下是一些可能对您有帮助的事情。

  • 您可能需要认真考虑的一件事是加载Bitmap的压缩版本:在加载Bitmap之前计算堆上可用的内存量。在此基础上,计算要加载的位图的大小,从中计算高度和宽度,然后加载位图。
  • 确保您没有泄漏位图。这是人们遇到的主要问题之一。这可能以多种方式发生,从泄漏的视图到泄漏的活动。要查看此信息,请分析您的工作记忆
  • 当没有内存泄漏时,GC会自动清除位图。在3.0之前的设备中,您必须调用recycle(),因为GC不能很好地完成工作。在3.0之后的设备中不需要这样做。虽然要小心,如果你在正在使用的Bitmap上调用recycle(),比如在ImageView中,你会得到一个例外。

答案 4 :(得分:0)

您总是可以尝试使用软引用的位图,但是它们可能会比您需要的更快地收集垃圾。