2012-10-29 46 views
1

我想创建一个可绘制与反映,这里是我的代码:为什么我创建的位图总是泄漏内存?

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 

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

+0

[检查此](http://android-developers.blogspot.in/2009/01/avoiding-memory-leaks.html) – Zombie

回答

2

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

在内存泄漏,你会看到在GC过于频繁,可以提示你在logcat的消息踢。

+0

我一开始也这么想,但如果我一直在调用这个函数多次,来电createBitmap在这个函数会导致java.lang.OutOfMemory例外。 – liuyong

0

这就是由谷歌说:

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

位图占用了大量的内存,特别是对于丰富相似图片照片。例如,Galaxy Nexus上的相机拍摄高达2592x1936像素(500万像素)的照片。如果所使用的位图的配置是ARGB_8888(从Android 2.3以后的默认),则此图像加载到内存中大约需要的存储器(2592 * 1936 * 4个字节)19MB,立即排出的每个应用限制某些设备

尝试阅读此链接Android developer