为什么此图像切换代码存在内存泄漏? [英] Why this image-switching code has memory leak?

查看:106
本文介绍了为什么此图像切换代码存在内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个简单的android应用程序,它使用ImageView来显示图像.单击一个按钮时,它将基于当前图像生成一个新的位图,并替换旧的位图.

I'm write a simple android application, which uses an ImageView to display an image. When click on a button, it will generate a new bitmap based on current image, and replace the old one.

我使用的图像不大: 220 x 213 .

但是在模拟器中,当我单击按钮第5次时,它将引发错误:

But in the emulator, when I click the button the 5th time, it will throw an error:

 java.lang.OutOfMemoryError: bitmap size exceeds VM budget

我读了一些文章:

  1. java.lang.OutOfMemoryError:位图大小超出了VM预算-Android
  2. http: //androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/
  3. http://android-developers.blogspot.de /2009/01/avoiding-memory-leaks.html
  1. java.lang.OutOfMemoryError: bitmap size exceeds VM budget - Android
  2. http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/
  3. http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html

但仍然不能解决我的问题.

But still not fix my problem.

我的代码是:

public class MyActivity extends Activity {
    private Bitmap image;
    private ImageView imageView;
    private Button button;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        this.button = (Button) findViewById(R.id.button);
        this.imageView = (ImageView) findViewById(R.id.image);


        this.image = BitmapFactory.decodeResource(getResources(), R.drawable.m0);
        this.imageView.setImageBitmap(image);

        this.button.setOnClickListener(new View.OnClickListener() {
            private int current = 0;

            @Override
            public void onClick(View view) {
                Bitmap toRemove = image;
                Matrix matrix = new Matrix();
                matrix.setRotate(30, 0.5f, 0.5f);
                image = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, true);
                imageView.setImageBitmap(image);

                if (toRemove != null) {
                    toRemove.recycle();
                }
            }
        });
    }
}

您可以看到我在删除图像上调用了toRemove.recycle().但这似乎没有效果.

You can see I've invoked toRemove.recycle() on the removing image. But it seems no effect.

更新:

由于错误仅在我第五次(不是第一次)单击按钮时发生,所以我们可以看到图像尺寸不是问题.而且在我的代码中,我尝试在生成新映像后释放旧映像,因此我认为旧映像尚未正确发布.

Since the error only occurred when I click the button the 5th time(not the first time), we can see the image size is not a problem. And in my code, I tried to release the old image after generating a new one, so I think the old image has not been released proper.

我调用了toRemove.recycle(),这是释放图像的正确方法吗?还是我还要使用其他东西?

I have invoked toRemove.recycle(), is it the correct method to release an image? Or do I shall use something else?

最后:

Emile是对的.我添加了一些代码来记录大小,您可以看到它每次都在增加:

Emile is right. I added some code to log the size, and you can see it increasing each time:

08-28 13:49:21.162: INFO/image size before(2238): 330 x 320
08-28 13:49:21.232: INFO/image size after(2238): 446 x 442
08-28 13:49:31.732: INFO/image size before(2238): 446 x 442
08-28 13:49:31.832: INFO/image size after(2238): 607 x 606
08-28 13:49:34.622: INFO/image size before(2238): 607 x 606
08-28 13:49:34.772: INFO/image size after(2238): 829 x 828
08-28 13:49:37.153: INFO/image size before(2238): 829 x 828
08-28 13:49:37.393: INFO/image size after(2238): 1132 x 1132

推荐答案

我不确定Bitmap.createBitmap()的工作方式,但由于错误与位图大小"有关

I'm not sure quite how Bitmap.createBitmap() works, but given the error is to do with the 'bitmap size'

java.lang.OutOfMemoryError: bitmap size exceeds VM budget

我认为每次单击图像的大小都会增加.因此,该错误是在第5次点击时发生的.

I would presume that the image is increasing in size with each click. Hence the error occurring on the 5th click.

我建议大小增加与旋转矩阵有关.旋转图像时,似乎并没有将旋转后的图像裁剪为图像的宽度和高度,而是增加了图像的大小.

I would suggest that the size increase is to do with the rotation matrix. When the image is rotated it appears that it isn't cropping the rotated image to the image width and height, but rather increasing the size of the image.

您将不得不尝试一些其他方法来在所需的w/h范围内操纵旋转.

You would have to try some alternative methods for manipulating the rotation within the w/h bounds you desire.

这个问题的答案(向下两个)显示了如果您愿意的话,如何裁剪旋转的图像. Android:如何在中心点上旋转位图

An answer (two down) to this question shows how to crop the rotated image if you so wished. Android: How to rotate a bitmap on a center point

RectF rectF = new RectF(0, 0, source.getWidth(), source.getHeight());
matrix.mapRect(rectF);

这篇关于为什么此图像切换代码存在内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆