1

I am trying to create a drawable with reflect, here is my code:

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;
}

The following log was shown every time createReflectedImage called, even if I just return null at the end of this function.

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

Could anyone help me figure out how this memory leak happened?

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
liuyong
  • 987
  • 10
  • 19

2 Answers2

2

This is not a memory leak. Every Android device has a maximum heap size per application. For performance reasons Android does not allocate that size to every application, instead it waits until the app needs more memory and allocates it. This message you see is the DVM allocating more memory when your app asks for it and is perfectly normal.

During memory leaks you'll see the GC kicking in too frequently which can hint you with messages in the logcat.

Ragunath Jawahar
  • 19,513
  • 22
  • 110
  • 155
  • I thought so too at first, but if I keep calling this function for several times, call to createBitmap in this function would cause java.lang.OutOfMemory exceptions. – liuyong Oct 29 '12 at 03:36
0

This is what is said by google:

Mobile devices typically have constrained system resources. Android devices can have as little as 16MB of memory available to a single application. The Android Compatibility Definition Document (CDD), Section 3.7. Virtual Machine Compatibility gives the required minimum application memory for various screen sizes and densities. Applications should be optimized to perform under this minimum memory limit. However, keep in mind many devices are configured with higher limits.'

Bitmaps take up a lot of memory, especially for rich images like photographs. For example, the camera on the Galaxy Nexus takes photos up to 2592x1936 pixels (5 megapixels). If the bitmap configuration used is ARGB_8888 (the default from the Android 2.3 onward) then loading this image into memory takes about 19MB of memory (2592*1936*4 bytes), immediately exhausting the per-app limit on some devices'

Try to read in this link Android developer

Kingfisher Phuoc
  • 8,052
  • 9
  • 46
  • 86