为什么我创建的位图总是泄漏内存?

时间:2012-10-29 03:07:38

标签: android memory-leaks bitmap

我正在尝试用反射创建一个drawable,这是我的代码:

public Drawable createReflectedImage(Drawable d) {

    int width = d.getIntrinsicWidth();
    int height = d.getIntrinsicHeight();
    Bitmap originalImage = Bitmap.createBitmap(width, height,
            Config.ARGB_8888);
    d.setBounds(0, 0, width, height);
    Canvas canvas = new Canvas(originalImage);
    d.draw(canvas);

    final int reflectionGap = 4;

    Matrix matrix = new Matrix();
    matrix.preScale(1, -1);

    Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
            height / 2, width, height / 2, matrix, false);

    Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
            (height + height / 2), Config.ARGB_8888);

    canvas = new Canvas(bitmapWithReflection);

    canvas.drawBitmap(originalImage, 0, 0, null);

    Paint deafaultPaint = new Paint();
    canvas.drawRect(0, height, width, height + reflectionGap, deafaultPaint);

    canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);

    Paint paint = new Paint();
    LinearGradient shader = new LinearGradient(0,
            originalImage.getHeight(), 0, bitmapWithReflection.getHeight()
                    + reflectionGap, 0x70ffffff, 0x00ffffff,
            TileMode.MIRROR);

    paint.setShader(shader);

    paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));

    canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
            + reflectionGap, paint);
    BitmapDrawable drawable = new BitmapDrawable(getContext()
            .getResources(), bitmapWithReflection);
    originalImage.recycle();
    reflectionImage.recycle();
    return drawable;
}

每次调用createReflectedImage时都会显示以下日志,即使我在此函数结束时只返回null。

10-29 10:56:48.541: I/dalvikvm-heap(23989): Grow heap (frag case) to 19.332MB for 960016-byte allocation

有人能帮我弄清楚这个内存泄漏是怎么发生的吗?

2 个答案:

答案 0 :(得分:2)

这不是内存泄漏。每个Android设备都有每个应用程序的最大堆大小。出于性能原因,Android不会将该大小分配给每个应用程序,而是等待应用程序需要更多内存并分配它。您看到的这条消息是DVM在您的应用程序要求时分配更多内存并且非常正常。

在内存泄漏期间,您会看到GC过于频繁地踢,这可能会暗示您使用logcat中的消息。

答案 1 :(得分:0)

这就是谷歌所说的:

移动设备通常具有受限制的系统资源。 Android设备可以只有16MB of memory available一个应用程序。 Android兼容性定义文档(CDD),第3.7节。虚拟机兼容性为各种屏幕尺寸和密度提供所需的最小应用程序内存。应优化应用程序以在此最小内存限制下执行。但是,请记住,许多设备配置了更高的限制。'

Bitmaps会占用大量内存,尤其是对于像照片这样的丰富图像。例如,Galaxy Nexus上的相机拍摄的照片最高可达2592x1936像素(5百万像素)。如果使用的位图配置是ARGB_8888(默认情况下从Android 2.3开始),那么将此图像加载到内存中需要大约19MB的内存(2592 * 1936 * 4字节),立即耗尽某些设备的每个应用程序限制

尝试阅读此链接Android developer