Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory allocation in Java - Android

If I have:

Bitmap bitmap = Bitmap.create(..); // instance a
bitmap = Bitmap.create(...); // instance b
bitmap = null;
bitmap = Bitmap.create(...); // instance c
bitmap.recycle();
bitmap = Bitmap.create(...); // instance d
bitmap.recycle();
bitmap = null;

Once this code is executed, which of the 4 instances are still in memory? I know .recycle() instructs the native code to deallocate all resources to that object, but there's no guarantee of when that happens.

The reason I'm asking, is let's look at the following loop:

Bitmap bitmap = null;

while (true) {
    bitmap = Bitmap.create(...);    
}

This I assume will eventually crash the app (out of memory)? If so, how should this loop be rewritten? (If I'm using bitmap to animate and display changed state).

like image 243
StackOverflowed Avatar asked Nov 13 '22 00:11

StackOverflowed


1 Answers

Java (and by extension Android) use asynchronous garbage collection to clean up allocated memory. The collector runs in the background freeing what memory it can. What this means is that at no point in time can you guarantee* how many unreachable objects have been cleaned up vs. those that are still pending.

Immediately after your first code block has finished executing it's possible all four Bitmap objects still exist on the heap, but at some point the garbage collector will run, determine that they're all no longer reachable, and free up their associated memory.

The same thing is true in your second code block; some arbitrary number of objects will still exist on the heap even though they are no longer reachable, however the GC will do its best to clean them up as this happens. In practice the GC is very good at cleaning up such short-lived objects, so it may even be able to keep pace with your loop (but that isn't a guarantee).

The JVM/ART will do its best to avoid an OutOfMemory situation, including an aggressive last-ditch garbage collection to attempt to reclaim any possible memory it can to keep the application running. Therefore it's unlikely your second loop would cause any issues, but it'd be easy enough for you to test.

Hopefully you're not literally creating and immediately discarding thousands of Bitmap objects; presumably they're being used for at least some period of time during which you aren't just creating more Bitmaps that literally go unused (if so, that's your problem).

* There are tricks, such as using PhantomReference, which do let you monitor the status of garbage collection, however these will put more burden on the GC and thus aren't a good idea - or necessary - in general.

like image 100
dimo414 Avatar answered Dec 20 '22 11:12

dimo414