Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy this image-switching code has memory leak?
    primarykey
    data
    text
    <p>I'm write a simple android application, which uses an <code>ImageView</code> to display an image. When click on a button, it will generate a new bitmap based on current image, and replace the old one.</p> <p>The image I used is not big: <strong>220 x 213</strong>.</p> <p>But in the emulator, when I click the button the <strong>5th</strong> time, it will throw an error:</p> <pre><code> java.lang.OutOfMemoryError: bitmap size exceeds VM budget </code></pre> <p>I've read some articles:</p> <ol> <li><a href="https://stackoverflow.com/questions/1949066/java-lang-outofmemoryerror-bitmap-size-exceeds-vm-budget-android">java.lang.OutOfMemoryError: bitmap size exceeds VM budget - Android</a></li> <li><a href="http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/" rel="nofollow noreferrer">http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/</a></li> <li><a href="http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html" rel="nofollow noreferrer">http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html</a></li> </ol> <p>But still not fix my problem.</p> <p>My code is:</p> <pre><code>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(); } } }); } } </code></pre> <p>You can see I've invoked <code>toRemove.recycle()</code> on the removing image. But it seems no effect.</p> <hr> <p>UPDATE:</p> <p>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.</p> <p>I have invoked <code>toRemove.recycle()</code>, is it the correct method to release an image? Or do I shall use something else? </p> <hr> <p>FINALLY:</p> <p>Emile is right. I added some code to log the size, and you can see it increasing each time:</p> <pre><code>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 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload