2

I have a screen where I have to show two similar images on screen . The size of both these images is dynamic but they covers most of the screen. When I navigate to this screen in my app, I see a spike of 12MB in Memory Monitor in AndroidStudio meaning both these images is using that 12MB as there is no other UI element on that screen and as both these images are similar takes takes equal amount of screen space, I guess each consumes 6MB of memory when shown. The dimensions of both these images are 1174 x 1174 pixels and the size is 396KB in res directory.

I have tried using Glide but I see same memory spike when these images are loaded through Glide too. Even Glide can't help if the app tries to take more memory than available and there is heavy usage of images in other parts of my app. So there is always memory crunch and I'm getting lot of OutOfMemory exceptions in the app where these two images are shown.

So my question is how can I reduce the memory usage of those images? Also why does the image takes 6MB of memory when it's size is 396KB in res folder?

Harry
  • 1,151
  • 11
  • 27

1 Answers1

2

I am guessing you did not compress your images, use https://github.com/zetbaitsu/Compressor very great at image compression. Also i am also guessing you did use Glide caching strategies.

Glide, however, caches the original, full-resolution image and additionally smaller versions of that image. For example, if you request an image with 1000x1000 pixels, and your ImageView is 500x500 pixels, Glide will put both versions of the image in the cache.

  1. DiskCacheStrategy.NONE caches nothing, as discussed
  2. DiskCacheStrategy.SOURCE caches only the original full-resolution image. In our example above that would be the 1000x1000 pixel one
  3. DiskCacheStrategy.RESULT caches only the final image, after reducing the resolution (and possibly transformations) (default behavior)
  4. DiskCacheStrategy.ALL caches all versions of the image

To answer your answer you need to manually keep track of the cache volume in android.Try forcing an garbage collection,Normally, VMs perform garbage collection only when absolutely needed, since it’s expensive. However, it can be useful to force garbage collection in certain circumstances. For example, when locating memory leaks, if you want to determine whether a large object was successfully released already, you can initiate garbage collection much more aggressively than usual.

Hope this was helpful.

Remario
  • 3,813
  • 2
  • 18
  • 25
  • those images are very large – Remario Apr 24 '17 at 22:18
  • try using the above library it is good, also try no caching for disk strategy and track your changes – Remario Apr 24 '17 at 22:20
  • also if your images are portable network graphics(PNG) or jpeg consider using TInyPng first to apply compression. – Remario Apr 24 '17 at 22:21
  • The library you posted is only used for compress files on storage whereas images in my app reside in drawable folder. You mentioned that images are very large, can you explain in what sense are they large? – Harry Apr 25 '17 at 09:46
  • I used TinyPng to reduce the size of the image and still loading the reduced size image consumes same amount of memory. It has on effect. – Harry Apr 25 '17 at 10:49
  • oh that is indeed strange, are you loading them through setDrawableResource, the library can work for drawable, for example get the uri of the image in drawable folder, create a file stream, then apply the compression, then after compression, listen for file and then set image. Consider using observables thats how i solve mine – Remario Apr 25 '17 at 12:52
  • Also mind sharing how you load your images currently excluding glide that is! – Remario Apr 25 '17 at 12:53
  • I'm setting the drawable id's to imageviews in the xml. But I'll try it your way and get back to you. – Harry Apr 25 '17 at 15:06
  • I used a low resolution image and it resolved the issue. – Harry May 08 '17 at 14:00
  • define low in this case? dimensions? – Remario May 08 '17 at 14:33
  • Initially the image was of resolution 1174 x 1174 pixels as I mentioned and was present in the nodpi drawable folder. So the image was consuming 1174 X 1174 X 4 bytes =~ 6MB. Now I added density specific images in the drawable folder which are of following resolutions: 360 x 360(mdpi), 540 x 540(hdpi), 720 x 720(xhdpi), 1080 x 1080(xxhdpi) and 1440 x 1440(xxxhdpi). Now there is no memory crunch on low memory devices. The problem was the image was consuming ~6MB on all devices. Now it only consumes fraction of that memory. – Harry May 09 '17 at 13:16