In android app, images can be changed through run-time (e.g. layout-bg, ImageButton-src, Button-bg, ..etc), so what happens to the old image in the terms of memory occupation? is it removed or still occupy a portion from the memory? and if it's not removed, how can I clear the memory from this image?
UI part of android is mainly written in Java -- once all references to a bitmap is gone, the bitmap will be flagged for garbage collection. If you do not use a bitmap texture, and you have no reference to that bitmap anywhere in the code the memory will be freed immediately. Please be careful about memory leak in android. Read this:
http://android-developers.blogspot.ca/2009/01/avoiding-memory-leaks.html
Related
I work with several large drawables and I don't know how to manage memory leaks.
I tracked the heap size of my application and it doesn't stop to grow (as the allocated memory).
It is especially the "byte array (byte[])" type which grows up and never decrease. (in the DDMS Heap view on Eclipse)
My application is composed of one activity which uses fragments.
Those fragments are displaying several large images.
I tried to set drawables callback to null, set drawables to null, clear my volatile cache (which prevent my app from doing too many disk IO) when I pop back a fragment but the heap never decrease.
In fact, each time I call :
Drawable.createFromResourceStream(context.getResources(), value, new FileInputStream(f), f.getName(), opts);
the heap grows up. How can I free memory ?
Thanks !
A memory leak happens when Java finds objects in the memory that are referenced by your code which is preventing the Garbage Collector from freeing this memory. A common cause in Android is referencing the Activity context rather than the Application context. Make sure your context references the Application (i.e. use getApplicationContext rather than using this. Check this video for explanation on Memory leaks and also check this question.
The question seems answered but a post by Romain Guy seems relevant to get more info: Avoiding Memory Leaks.
Apparently, if you (for example) set a drawable as a background image to a text view by using setBackgroundDrawable* (thus attaching the drawable to the view) then change the orientation (destroying the Activity and redrawing the UI) the drawable will still have access to the old activity (after the old activity's destruction), thus creating a memory leak.
*(as a side note - setBackgroundDrawable has been deprecated since API level 16)
I try to implement a Gallery where each item is a big image for a good zomm-in function.
The problem is the management of the memory.
When i try to go to the fourth element android goes to Out Of Memory, so i try to recycle the images not displayed, but android goes to RunTimeException for try to use a recycled image when i come back.
Also i try to change the bitmap of the bigs images not displayed with bitmap of small images but always goes to Out Of Memory.
How can i do, for manage the memory of the Gallery?
After you do call recycle(), make sure you don't use that Bitmap reference again as that will cause a runtime exception if certain methods are invoked. Try using SoftReferences wrapped around your bitmaps. This will guarantee that all of the memory that is no longer references will be reclaimed before an OutOfMemoryError is thrown.
I have many pictures in my #drawable directory which are connected to xml layout via background property:
i.e
<ImageButton android:background="#drawable/background1" ... />
I have many activities, so, when activity is destroyed (BACK is pressed), the heap isn't freed. So, the question is:
Does android load everything in the memory once and make heap free only when application is destroyed? How I can prevent in this case memory consumption ? Only through image compression or dynamically loading background and images?
I think Android has a its own garbage collector, but for proceed it its take sometimes instead of relevent momory as the object is not in use. And whenver the bitmap is created its memory occupied in native heap and heap garbage collector is to lazzy.
So if possible use dynamic Image loading instead of static, and try to use your own recycler or freed the memory of your bitmap.
EDIT:
The gc() does not handle so-called short lived objects as fast as we
would like.
Keep the number of view objects at a stable level*, and recycle them instead of destroying and creating new ones.
A nice post of Avoiding memory leaks by Roman Guys refer it.
If I am wrong please let me know. And please share some more information on this.
Thanks.
I am trying to decode a bitmap with pixel size 1024*683 with the api
decodefile(filepath) but process runs out of memory while decoding the
image.
I need the bitmap object for this image at one go without any scaling
as i have to work with NDK reading the pixel values using this bitmap.
Therefore any scaling or sampling method can't be applied in my case.
I wonder how come this is possible that just decoding a file with
such size would need any in-around method. There is enough heap size
available for this process.
Your opinion and perspective in this matter will be appreciated.
Thanks
Nawab
I faced the same problem when I had memory leaks in one of my activities. There were not only view leaks, but bitmap leaks too. And memory consumed by bitmaps is not taken into account when DDMS shows free heap space.
When displaying a gallery with lots of large bitmaps (fullscreen, wvga), I quite frequently get out of memory issues. I assume this is related to bitmaps not being recycled. When/how can I force bitmaps to be recycled?
I also noticed that in the getView method of simpleCursorAdapter, convertView is always null. I assume this means that the old view is not recycled? Even when scrolling back and forth, a new view is created each time. However, scrolling back and forth does not cause out of memory issues, that only happens when the total number of images is large enough.
When using the same adapter with a ListView, views are recycled, so it seems the problem is with the Gallery.
What can I do to force views and/or bitmaps to be recycled? What else can I do manage memory without reducing gallery size and bitmap quality.
You can use recycle() if you are sure tou won't use a bitmap anymore, for example in any operation with a temporary bitmap. But...You can use BitmapFactory.Options, for ex:
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inPurgeable=true;
Bitmap bitmapTemp = BitmapFactory.decodeResource(getResources(), R.drawable.intro, bitmapOptions);
What it does? the option inPurgeable will asume that once the system needs memory and your bitmap it's no more useful, system will recycle this memory allocation by itself. If for some reason you cannot load an image with the BitmapFactory then you can use Recycle() and it's recommendable to call de garbage collector then with system.gc(), this is usefull if you're developing for example a game, because when garbage collector it's activated when you system it's low on memory, it will consume some valious milliseconds.
You should be very careful with bitmaps, they're not stored on the "normal" memory used by your app, it's stored on a "general" memory used by all your apps, unless you are using Android 3.0.
If you get a memory leak and can't find it looking at the heap... you should take a look at your code loading and using bitmaps.
Hope it helps.
You never need to recyle a Bitmap. However, you can do it, and it will help when you have OutOfMemory errors. But don't it until the bitmap is not needed any more, because (from the javadoc)
it will throw an exception if
getPixels() or setPixels() is
called, and will draw nothing. This
operation cannot be reversed, so it
should only be called if you are sure
there are no further uses for the
bitmap.
In your case, I assume you should:
use thumbs which are bitmap opened with BitmapFactory.Options.inSampleSize or MediaStore.Images.Thumbnails
Have only at most one full size bitmap in memory (maybe one preloaded in you can afford)