how to prevent out of memory error in android - android

I am new on android and I am developing an application in which I am downloading images from server in drawable array. Everything is right but when the activity(in which drawables are downloade one by one in thread) loads, after some time it gives out of memory error.
Please help.

try to use streams instead loading it at once and use SoftReference. and read http://davidjhinson.wordpress.com/2010/05/19/scarce-commodities-google-android-memory-and-bitmaps/

It's not a memory leak you have, you're simply trying to put more images into memory at once than will fit
In order to solve that you can either
Use an array of SoftReference<Drawable>, store each drawable in the array as new SoftReference(myDrawable). When retrieving a SoftReference, check that SoftReference.get() is not null. If it is null the drawable has been reclaimed by the Garbage Collector (GC) and you will need to re-download it to memory, if it is not null then SoftReference.get() returns the drawable you stored in the SoftReference.
Limit the size of the array to an amount that will fit in memory. You will have to implement some system of storing new images over the older ones if the array has got to it;s maximum size (e.g. place the new image on the end of the array and remove the first element of the array)
SoftReferences allow the GC to reclaim the memory taken up by objects when low memory situations are encountered.

Related

How to clean memory after exiting activity

As title says, I have about eight acitivies with layout full of high-res images. On weaker android devicies with low RAM memory it opens each activity alone, but when I try open another, it crashes. But when I restart app and open that activity, it works. What should I do to clean apps memory from these images from first activity to be able to open another activity? Does onDestroy() clean it?
If it like resource images in xml layout, you don't need to clean up them, Android will do it for you. But if you use some big bitmaps objects.
Bitmpap bmp; // not null
bmp.recycle();
bmp = null;
final boolean bmpIsRecycled = bmp.isRecycled()
// Returns true if this bitmap has been recycled.
Free the native object associated with this bitmap, and clear the reference to the pixel data. This will not free the pixel data synchronously; it simply allows it to be garbage collected if there are no other references. The bitmap is marked as “dead”, meaning 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. This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap.
And actually when your app crashes, what error log do you have? Maybe it's not related with memory leak?

Android - do Bitmaps automatically get recycled when an activity finish()?

Do Bitmaps automatically get recycled when an activity finish()?
Or do we have to call recycle() the bitmaps in onDestroy()?
In the Pre Android 3.0 you need to recycle it, because the bitmap is stored in the native heap.
as long as you're not referencing them by any still alive object: they get garbage collected by the GC without any need to further interaction.
On Pre-honeycomb device
Bitmap Object reference allocated on Dalvik Heap
Pixel information stored on Native layer
recycle() or finalizer() needed to restore memory
On Post honeycomb its standard like any java object

DDMS Heap - 1-byte array(byte[], boolean[])

I experience some memory leaks in my android application. I've already used MAT to analyze the memory usage. But I have one question from the DDMS perspectiv in Eclipse, what does 1-byte array[byte[], boolean[]) mean?
Is this specific for my application? You can see that this is the big memory leak issue, this always increases in size, and the rest will increase and decrease randomly. My guess is that the GC doesn't catch this type. Can anybody explain why this happen, with this little information?
One byte array is the designation for any data structure that is organized as a single byte array. In you case and with that size, I would bet in a Bitmap or a Drawble.
Most common reasons for memory leaks are static object not properly managed and holding references to:
Context
View (which holds reference to context (and possibly also to bitmap)
Thread (which are not easly collected by GC)
Handler (which holds reference to context)
Most of them can be solved ensuring that you set the object to null when it's no long required.
Regards.
A byte and a boolean are each 1 byte. If you have an array of those you have a "1-byte array".
A ByteBuffer for example should internally hold one of those.
You have a total of 614 of them where the smallest one be a byte[24] (or boolean[24]), the largest one is 3MB. All of them together use 104MB.
The GC will get rid of them if they are no longer referenced.
For example when you put
private static byte myArray[] = new byte[3 * 1024 * 1024];
in one of your classes and never set it back to null (myArray = null) then this one can't be garbage collected because another Object has a reference to it. The object would be the class itself (as in String.class). The class object can't be garbage collected since classes are never unloaded. (they are referenced by their ClassLoader which could itself be referenced / loaded by another ClassLoader and you can't create Objects & use classes without them - they need to stay and they need to keep a reference to their classes)
It's usually not that simple but often start with static somewhere.
Within MAT (after you force GC) look at the reference chain for the objects that are no longer intended to stay alive and identify the one Object that holds the reference. Set that one to null in your code and your leak is gone. Explained in more detail here:
http://android-developers.blogspot.de/2011/03/memory-analysis-for-android.html
I ran to this problem tonight and almost I checked every bit of code but I couldn't find anything.
What I did was starting the app from intelij and then pressing home button and open the app again. Every time the app heap was doubled.
Finally I discover when I launch the app from ADB and press the home button and open the app again it doesn't bring back the old activity, it just start a new one. When I pressed finish it starts to cycle through all of them. It's like they are treated as two different intent. So I put android:launchMode="singleTop" on the main activity in manifest and it resolved the problem.
Although it's not the main cause of this problem but if you encountered this check this out before anything. It wasted three or four hours for me.

How to use an ImageView without de/allocating memory

I have an application that uses a flip-book style animation with thousands of images. APK size isn't an issue due to it being an internal only application that will never be put on any app store.
The issue I am having is my animator is a sub-classed ImageView that switches out images at 15 frames per second and each time I call setImageURI Garbage Collection then runs. So is there an alternative method to setImageURI that wont cause Garbage Collection to be run?
Edit: A little more background information.
My app has ~12 sequences and 6 of them contain 1609 Images and different events need to be called at certain frames. Another need is for the user to be able to stop on any frame to survey the situation and either preform an action or continue down the sequence. A 3D engine would have been the ideal solution but this method was brought up as the user doesn't need complete freedom and is on a "rail" the entire time.
This is the meat of the application and where the problem occurs
try {
((BitmapDrawable) getDrawable()).getBitmap().recycle();
setImageURI(imgUri);
refreshDrawableState();
} catch (Exception e) {
e.printStackTrace();
}
The Garbage Collector is running because you're exchanging one image for another which dumps the previous. It's going to happen every time you lose references to the images.
Here are a couple possible methods to consider.
Since you mentioned it's a flipbook, build and assign an AnimationDrawable to the ImageView which will act as a frame-by-frame animation (exactly what a flipbook is). This loads all the images at once and will keep them around until you lose a reference to the AnimationDrawable.
Store all the images as SoftReferences to cache the images. A SoftReference will keep the object in memory until memory is needed to be collected. This will slow the frequency of the garbage collector (assuming this is the cause). Use BitmapFractory to build the image and setImageBitmap to assign it to the ImageView. The other advantage of this is it allows you to build images on threads before you assign it to the ImageView.
Maybe it's because your Image need to much memory, and the android need call the GB to free more mem trying to avoid crashing your program

Android, An impossible Memory Leak, How to find it with eclipse?

I am metting an OutOfMemory exception after a while, while inflating an XML View with a bitmap.
The problem occurs after opening many times activities that are using many bitmap but always inflated from the XML.
I check with MAT the Memory.
First question : I don't retain any of my Activity in memory
- If I filter on the name of my Activity, i get Objects = 0, but on some activities
I could see RetainedHeap >= 302. Does this indicate a leak ?
After that, I try to compare my memory in different point of time, to see the objects that have been created. But I can't find any thing significant.
My Question is : If I don't retain activities in memory what could be the leak reason ?
What tools/Method to use to find it ?
Regards,
Olivier
Try setting all references to the bitmaps to null when the Activity is destroyed. This may not answer your questions but it should solve your problem.
If you have big source images then scale them to target size: Strange out of memory issue while loading an image to a Bitmap object
Cache Bitmaps (but not Drawables!!) in a List (or Map) and save them in onRetainNonConfigurationInstance(): http://developer.android.com/resources/articles/faster-screen-orientation-change.html

Categories

Resources