Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android out of memory prevention

I have a list that shows thumbnails (small images) downloaded on the fly from the web. At some point, the process runs out of memory. How can I tell that the free memory is about to run off, so I can stop downloading more images?

I would like to know it in advance in order not to be on the edge of out of memory.

Note: It is not a memory leak, just lots of downloaded bitmaps.

Thanks.

like image 573
AlikElzin-kilaka Avatar asked Apr 07 '11 10:04

AlikElzin-kilaka


People also ask

How do I stop Android out of memory error?

Check that the image size is smaller than the available memory before attempting to load it. So the most efficient way to handle OutOfMemoryException is to architecture your application in such a way that it never attempts to load lots of data into memory in order to avoid the exception.

What are the best practices to prevent memory leaks Android?

Causes of Memory Leaks and Their SolutionsOne should not use static views while developing the application, as static views are never destroyed. One should never use the Context as static, because that context will be available through the life of the application, and will not be restricted to the particular activity.

What is eating up my RAM Android?

To find out which apps are using your memory, you must first enable the Developer options. To do that, open the Settings app and then tap About Phone. Scroll to the bottom of that window and then tap Build number 7 times. After the seventh tap, you'll be informed that the Developer options has been enabled.


1 Answers

1) You have to be your own browser.

Download your thumbs to the SDCard rather than keeping them in RAM. Shrink/rotate them before you save them so that when you next need to load them the load is "free" from the SDCard instead of expensive from the internets. (Ie: like any browser, use a local file cache).

Release any interim Bitmap objects you may create to do this.

Learn how to use the "inSampleSize" param to unpack Bitmaps at less than original resolution.

If the files you write end in an image extension (.jpg, etc) they will appear in the Gallery, so don't save your thumbs with obvious image filenames.

2) Create a tiered cache system (Bitmap > SDCard > Internets).

When you unpack a thumbnail, save it in a SoftReference cache. If you need to use that thumbnail, ask for it from the cache. If the VM needed more memory, your SoftReference instance may return null.

If you get null from your bitmap cache, then check to see if you've already put your url on the SD card and load it into the bitmap cache from there.

If you get null from your filesystem, then go download the image from the internet and save it to SDCard and stick it in your bitmap cache.

3) Release resources that aren't being used.

In the same way, make sure you clear the Bitmaps from the Views they have been placed in as soon as the View is offscreen (if your Views live in a ListView or other Adapter-based element, this is essentially "free" from recycling the View elements) -- However, if you have ImageViews instantiated with Bitmaps and they're not immediately displayed on the screen, you're probably wasting heap.

You can simply call setImageBitmap(null); on an ImageView and the reference to the Bitmap will be dropped (so that if the only ref is the SoftReference when it's not being used).

4) Pay attention to what thread you are in.

Remember, you must download bitmaps from a non-UI thread (we use a Service instance to act as a queue of intent requests), and you must attach bitmaps to View instance only in the UI thread.

You'll need to create a good queued system to load everything into your bitmap cache off the UI thread and then use a Handler to tell your bitmap cache to fill ImageViews on the UI thread.

5) Pay attention to your download Queues.

If you're like us and you have both thumbs and full-sized images, you need to either manually use a priority queue to put your image requests before you thumb requests, or use two different Services (that enqueue their separate Intents) to download thumbs vs full images.

Otherwise you might queue up a screen full of thumb downloads but not respond with a full image until after all of the thumbs complete.

6) Ask the system how much RAM you have.

  Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
  Debug.getMemoryInfo(memoryInfo);

7) "onLowMemory()" doesn't do what you expect.

It is for when the user is running too many applications on the phone and the OS needs to recover physical memory from all of the running apps.

This is totally separate from running out of application VM heap like you'll easily do by loading too many bitmaps.

To the best of my knowledge you will not get a warning, you'll just crash (tho you can track memory info with the above call).

Hope that helps with trying to make something smart about downloading and displaying thumbs from the internets.

mig

like image 90
mig Avatar answered Oct 07 '22 12:10

mig