开发者

Android out of memory prevention

开发者 https://www.devze.com 2023-02-23 06:10 出处:网络
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.

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 开发者_如何学JAVAa memory leak, just lots of downloaded bitmaps.

Thanks.


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


I use SoftReference to hold the bitmap objects. The list only needs the current visible images. Thus, I never need to worry about running out of space.

The minus is that when I see the images, scroll down (causing some SoftReferences to clear the Bitmaps), then scroll back again to the same place - the images get downloaded again :(

Also, the SoftReferences get cleared very fast. I would expect them to save the inner bitmap longer.


You should use inSampleSize option of BitmapFactory.Options while creating the bitmaps.

Also, some of the tips in Android: out of memory exception in Gallery has been useful for me in keeping a check on the memory available.


You can over-ride the Activity's onLowMemory() method for custom handling such scenarios

0

精彩评论

暂无评论...
验证码 换一张
取 消