I knw this is one of the most discussed question but I couldn't figure out my way with the questions available here.
I'm decoding the bitmap as below
BitmapFactory.decodeFile(sdCardPath);
While executing above line randomly system running out of memory. This is not happening always . For example if I try to decode same image 3 times, it might go out of memory 3rd time or even 4th time. This error observed randomly.
How to solve this issue??
Thanks for your time in advance
First, if this is a bitmap that you are referencing from your assets, I would recommend moving it to your res/drawables folder, and access it as a drawable. If this is not the case, you are making too many references to this image without, as #VargaPeter pointed out, garbage collecting. The best way to garbage collect when using multiple bitmaps is to call recycle(), however System.gc() is often used as well (though in practice, you should use recycle(). If you are still having problems, you must either (a) allocate more space using the Android NDK (discouraged), or (b) use a smaller bitmap image (recommended). I know for certain there are posts discussing option b in several places on this site, as I had this same problem once before.
The Bitmap that you get back probably isn't garbage-collected because of a lingering reference.. Try to use the same reference if the app's design allows, or reusing a small number or references...
Related
I'm currently working on an android app with several activities. Most of the time, the app works fine, but from time to time an Out of Memory Exception occurs. (usually when trying to load the large background image for the next activity)
I couldn't find any obvious memory leaks, so I created a heap dump when the exception occurred (like described here) and tried to analyse it with MAT.
I haven't done something like this before, so I wasn't sure what exactly I should be looking for. I started clicking through the larger byte objects and the second one seems to be a Bitmap belonging to an ImageButton:
The Path to GC roots shows me an com.android.internal.policy.impl.PhoneWindow instance:
The thing is, the only ImageButton in my whole application is in my launch activity and between that launch activity and the crashing activity are at least 2 more activities.
So why is this image still in the heap??
The ImageButton is simply defined in the layout xml file using the android:src attribute, nothing is done via Code there. There are also a lot of other smaller objects from earlier activities in the heap.
I also wrote a little HelloWorld application and took a look in the heap dump of it and it seems, that android keeps the objects of previous activities in the heap. If this is the case, then an Out of Memory Exception has to be thrown some day, so I guess something must be wrong on my analysis :/
You might want to look at Bitmap managing in the developer's documentation.
In particular: a bitmap is kept in memory as long as a reference exists to it. So, if you absolutely have to use large bitmaps for your buttons (as you are describing) you might be do better by loading it manually and using recycle as soon as your Activity disappears from sight.
Okay, I just found this and realized, that stopped activities (and their objects) are NOT destroyed as long they are on the back stack. Even not if the active one needs more memory.
With this knowledge it is obvious why these objects like that ImageButton are still in the heap.
I still have to figure out the best way to release these resources, but I guess this strongly depends on the application itself and is hard to answer in general.
Loading images onto ImageView in xml takes more memory?
I Have an Activity with around 7 imageviews(just like the app tray in any android phone.)
I am loading the images for each of the imageviews in the xml. Does this cause OutOfMemoryError?
Is there a way to recycle these?
Yes it is possible to attach drawable images to ImageView and you can remove them when you need.
imageview.setBackgroundResource(R.drawable.image);
or
imageview.setImageDrawable(drawable);
It does not cause any out of memory issue. Link to Doc
I have had this problem when i was loading Images. Sometimes this error can only be seen in Android emulator, sometimes this crashes the app in the mobile device too.
I solved this problem by following two steps:
Re-size the image if the resolution is too high.
Not having too many image objects open at the same time.
You can help the garbage collector out too, by assigning the image object to NULL when it is no longer necessary.
Unless necessary i would prevent opening too many images at the same time.
The factor by which you have to re-size, will depend on the actual size of the image.
Few Tips to address memory issues in Android:
1). Never use local variables to store large data / bitmaps specially in loops, As it will create un-necessary objects. I prefer class/instance variables in such situations. Try not to persist data unless it is required.
2). Avoid making calls to View.findViewById(..) wherever you can. Romain Guy has clearly stated in Google I/O 2010 that this method is costly (takes some KBs of memory to run), so call this method smartly like using ViewHolder which will consume less memory.
3) Use String pool effectively and use StringBuilder/StringBuffer when you are doing heavy operations with strings. Make sure that you are aware when you have to use StringBuffer as it is synchronized and again costly in comparison to StringBuilder.
I'm developing an android app that takes photos from camera or from library and does some stuff on them. The point is that after some use the application crashes. I have tried to make every possible optimization I could think of, ex call gc when possible, null the images when I leave an activity and even remove activities from the cache. But I still get out of memory errors and the app crashes.
Any suggestions on how to avoid such errors? Or even how to efficiently load images from drawables folder . Or any efficient way to throw all not needed objects when the activity changes so as to only use the needed memory for the active activity??
i had similar problems and ended up tracking them down to particular images. out of my 400 images there where three that where huge (file size wise). so i would check that all of your images have similar file size (usually it is directly correlated with image size)
also aren't bitmaps pretty big? how big is your average picture?
Did you manage Bitmap objects? If so, you have to call Bitmap.recycle() method.
Bitmap.recycle() API documentation
This question is linked with the answers in the following question:
Error removing Bitmaps[Android]
Is there any advantage of using Drawable over Bitmap in Android in terms of memory de-allocation ?
I was looking at Romain Guy project Shelves and he uses SoftReference for images caches but I'm unable to search where is the code which is de-allocating these Drawables when SoftReference automatically reclaims the memory for Bitmap. As far as I know .recycle() has to be explicitly called on the Bitmap for it to be de-allocated.
In my understanding, Bitmaps are typically better for performance if you don't need to do much image manipulation. However, I have run into memory leaks when I don't manually recycle them. My solution was to write a class to help me manage my images that provides an easy way to recycle all my bitmaps at certain points in my application. It also provides an easy way to reuse already loaded resources (including Drawables).
You don't need to call Bitmap.reycle(). This will be done for you in its finalizer. Doing it in the finalizer means the allocation will be delayed until finalizers run, so when possible directly calling recycle() can help with memory management.
Acc. to this page, starting from API Level 11, the Bitmap pixel data is stored in the Dalvik Heap along with the associated Bitmap. Thus calling .recycle is actually not required, unless you want to reclaim the memory manually for further use. Be sure to de-reference the bitmap too, just as an added measure.
PS: This was the link which explains hackbod's answer.
We have an Android application that throws out of memory error on Android 1.6. It is working fine on 2.0 onwards. We are trying to cut down on the runtime memory usage at this point.
We were thinking of reusing images – such as the background image of each screen. Is it possible to load the background image once in the memory at the time of app launch and reuse this cached copy in each screen rather than each screen loading the same background image increasing the overall footprint in the RAM?
We understand that there many other ways and best practices around runtime memory usage. But at this point, we just wanted to know whether this “image reuse” approach is really feasible?
If yes, how can we do this? Will it at all save any memory or the Android OS will still create multiple copies of the same asset for each screen not giving any benefit from the memory perspective?
Thank you very much for your time in reading my post.
If that background image is loaded as a Drawable from a Resource, it's bitmap data is already shared between all Drawables created that way. So no, it probably wouldn't benefit you in your particular case.
Yes you can reuse images.
It is usually done for ListViews where each row contains the same image.
In this case, you can get the Bitmap once in the constructor of your adapter, and reuse it in the getView() method, so you don't have to load it for each row. This trick is presented here
In your case, you could load your background bitmap in the onCreate() method of your main activity, save it as a public static attribute and then re-use it in all your activities.
But I think it won't make that much of a difference and surcharge the code for nothing.
As you are working on tweaking your UI, I suggest you watch the 2009 Google I/O Presentation by Romain Guy, if you did not see it yet. It shows a lot of useful tricks for boosting an UI's performances, especially when it comes to Bitmap manipulation.