Android clear the back stack if out of memory - android

When running on Huawei G300 with Gingerbread, my app crashes after 5 minutes or so of usage during setContentView() as it runs out of memory.
Each individual page doesn't use much memory, but from some research it seems the memory accumulates in the back stack.
Following advice here, I've replaced all my calls to startActivity with a utility function that also calls finish().
Android: Clear the back stack
This works; but there is no more back stack - the back button immediately quits the app, which isn't what I wanted.
Is there a way to only finish() the applications when I actually do run out of memory, and is that a reasonable approach to take?

You should search for memory leaks. A good tool for that is MAT if you use eclipse. MAT is not that hard to handle and you can get quickly some very valuable information.
One of the most common mistakes I have seen on Android is to keep a reference on a context that is dead. For instance, having a singleton holding a reference on one of the activities you created. There is no real reason for an app to crash the memory if it is well coded.

The Android Activity Manager was designed to manage this exact problem. The OS is designed to kill activities in the background and then restore them using onSaveInstanceState and onRestoreInstanceState.
The fact that your app is accumulating memory usage over time indicates to me that you may have a Context leak somewhere (a static reference to a view, adapter, etc. that has a reference to a Context), or that you have a caching mechanism that's not adjusting to your memory heap, or some other situation that's causing the out of memory.
I highly doubt that it's the Activities in the Back Stack causing the Out of Memory.
Here's a great guide on tracking down memory leaks on Android:
http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html

Memory is a very tricky subject in Android.
Every app gets a heap memory limit depending on the device. This heap memory is the dalvik memory plus the native memory, and you can see it as the total column in the dumpsys meminfo results. The dalvik memory deals with everything except with the bitmaps, that are allocated in the native memory (this is true for Android versions before Honeycomb).
Having said that I can only answer to some of your questions:
As far as I know, Android will always allocate memory for Bitmaps, even if they are the same. Therefore, in your case, every activity allocates memory for your background.
I don't know if its better to work with themes, you'll have to try that.
On one hand, activities are not reclaimed while the device has enough memory to deal with the next activity. Every activity is pushed to a pile from where it is recovered when you pressed the back button. In case Android needs more memory it removes one activity from the pile deallocating its memory (going back to question number one, maybe this is the reason for not sharing memory). On the other hand, you can set the activities launchMode to change this behaviour (have a look here).
I think MAT doesn't show native memory data. Use dumpsys meminfo's native column to see how much allocated memory for Bitmaps you have.
I have had hard times dealing with OutOfMemory problems myself. Now I have a much more clear idea of how it works and I am able to work with large files without running out of memory. I would highly recommend these two resources that helped me a lot:

Related

Free RAM in Android

I'd like to know some simple code that allows for freeing used memory that is no longer needed, in a similar way as a lot of memory freeing apps do.
Yes, I'm aware that this shouldn't be neccesary because Android manages memory on its own, but it looks like what's causing a non desired behavior in my app is having a lot of opened app occupying memory, so I think this is worthwhile to try, and check if the error happens any longer.
Could anyone hand me such a code? I'm not able to find any.
What I gather from the article is that you don't need to do anything to reclaim memory, but you can make garbage collection happen quicker and at specific times. What this means to me is that any arrays, Lists, large objects, etc. should be set to null when you are done with it. Granted, this should be done automatically when you leave a method or a View, but in case you are in a long running loop or staying on a page with lots of data hanging around, you can clean it up a little faster.
The Android Runtime (ART) and Dalvik virtual machine use paging and memory-mapping (mmapping) to manage memory. This means that any memory an app modifies—whether by allocating new objects or touching mmapped pages—remains resident in RAM and cannot be paged out. The only way to release memory from an app is to release object references that the app holds, making the memory available to the garbage collector. That is with one exception: any files mmapped in without modification, such as code, can be paged out of RAM if the system wants to use that memory elsewhere.
https://developer.android.com/topic/performance/memory-overview
You can also check your memory usage to see if that's really the problem. This is linked in the article above, but I thought I'd pop it out so it's easier to notice.
https://developer.android.com/reference/android/app/ActivityManager.html#getMemoryClass()

Why does app allocated memory permanently increase when showing fragments or starting activities?

I'd like to ask the community what they think about this behavior.
On my main activity I have one FloatingActionButton that when clicked will show a DialogFragment.
I followed Google's guidelines (I can't link it due to being a new user here at Stack Overflow) on how to properly create a DialogFragment so I believe I'm OK there. I've tested this behavior on fragments that use either onCreateDialog and onCreateView, and in both cases the results are the same.
When I click the button and I look at the memory usage, this is what I see:
Memory when fragment is first showed
So Android is allocating additional resources to compensate for showing a new fragment. That makes sense to me.
However, when I dismiss or cancel the dialog, the allocated memory doesn't drop.
When I open the same dialog using the same button, the allocated memory jumps again. I repeat this over and over (red arrows) until my allocated memory reaches just under 10MB and then (I believe) the Garbage Collector (blue arrow) kicks in and cleans up the app:
Memory after multiple showings
To me, this means I'm relying on the Garbage Collector to do the work for me and from what I understand that is not good practice.
Can anyone tell me if this is normal Android behavior, or is there something I'm doing wrong? If It isn't normal behavior, I will try to resolve the issue myself first before asking the community for further assistance (this is why I did not provide any code).
Thank you in advance.
I think this excerpt from this page sums up this behavior nicely.
Android does not offer swap space for memory, but it does use paging and memory-mapping (mmapping) to manage memory. This means that any memory you modify—whether by allocating new objects or touching mmapped pages—remains resident in RAM and cannot be paged out. So the only way to completely release memory from your app is to release object references you may be holding, making the memory available to the garbage collector. That is with one exception: any files mmapped in without modification, such as code, can be paged out of RAM if the system wants to use that memory elsewhere.
Basically, all you can do as an app developer is to release references to objects you allocate. So assuming you aren't keeping a reference to the object anywhere, like placing the fragment on the back stack for later use, the reference to the object should be released when the fragment is closed. At this point, it is available to the garbage collector to clear the previously allocated memory.
After that is done, it is up to the garbage collector to decide when to come in to action, so to say.

android memory issue - app uses a lot of ram

I have some problems with the memory usage of my android app and don't know what causes the high memory usage. When I start my app, it uses up to 40 mb ram (says DDMS) and when I open another app, my app gets immediately killed.
I read a lot about memory leaks and I'm unbinding drawables, running the GC and so on but my app still needs a lot of memory.
I have about 3mb resources in my app, but afaik they are loaded into ram on demand. Am I wrong? May this cause the 40mb of ram usage?
EDIT: I think I'm not having memory leaks because I can switch the orientation on each activity as often as I want and the app does not crash because of low memory. So it can't be a memoryleak, can it?
you need to do memory management into your android application, please free the resources which is no longer used, try to override onStop(), onDestroy(), onPause() methods of Activity which will keep track of activity stack.
in OnDestroy() method free your whole availed resources, so that another app can use the same resources again.
What data structures are you using? Very large data structures (long Lists, big graphs, big maps, etc) can quickly use up RAM.
It could also be that you're leaking the Context on orientation change in your app.
It could also be that your layouts are really badly designed along with some heavy data structures.
It's difficult to tell unless you describe a bit more about what your app tries to do.

android GoogleMaps memory leaks (?)

I'm working on a project dealing with map activities.
I was running a testing app consisting of a single activity, MaptestActivity, that extends MapActivity and does nothing else. I rotated the device more than ten times and I analyzed the heap dump with MAT. I noticed the existence of two instances of the main activity hanging around (a leak?). I re-tested the app with the same activity extending only Activity: the dump showed only one instance being kept by the system, the current one.
I'm attaching the screenshots of both cases. I'm not much into MAT, maybe I'm just misunderstanding the reults and everything works fine. Could you please shed some light on it?
With memory leak
Without memory leak
If you still have two activities in memory after rotating the device then you do have a memory leak. You can use MAT to see what is preventing that activity from being garbage collected by using the Histogram. Search on the class name to find it. Then right click on it and select list objects/with incoming references. That will list each occurrence of this object in memory. Right click on one of these objects and select Path to GC roots/exclude weak references. Now you should be able to see a hierarchy of objects, of which something is not getting cleaned up completely after the activity's onDestroy has finished. Things like hard references to a static context will cause this. To resolve some of our memory issues we've had to do things like use weakReferences where appropriate, and clean things up in onDestroy (like setting listeners to null).
Normally if your activities are not holding onto large objects like bitmaps you can "get away" with memory leaks since it would mean lots of app usage before you exceed the device's application heap size. But if say all of your activities hold onto a large bitmap, then leaking activities become much more of a big deal.
This is a good video: Memory Management for Android Apps
And a good article: Avoiding Memory Leaks
add the below line in for your activity in your manifeast file
android:configChanges="keyboardHidden|orientation"

Stack memory in Android

I'm writing an app that has a foreground service, content provider, and a Activity front end that binds to the service and gets back a List of objects using AIDL. The service does work and updates a database.
If I leave the activity open for 4-8+ hours, and go to the "Running Services" section under settings on the phone (Nexus One) an unusually large amount of memory being used is shown (~42MB).
I figure there is a leak. When I check the heap memory i get Heap size:~18MB, ~2MB allocated, ~16MB free. Analyzing the hprof in Eclipse MAT seems fine, which leads me to theorize that memory is leaking on the stack. Is this even possible? If it is, what can I do to stop or investigate the leak? Is the reported memory usage on the "Running Services" section of android even correct (I assume it is)?
Another note: I have been unable to reproduce this issue when the UI is not up (with only the service running)
I'm writing an app that has a
foreground service, content provider,
and a Activity front end that binds to
the service and gets back a List of
objects using AIDL.
If that's all just one application, get rid of the AIDL and get rid of the content provider. Or, at least, don't use them yourself -- those are for other applications to use. They add overhead that you do not need for stuff inside your own VM.
...which leads me to theorize that memory is leaking on the stack. Is this even possible?
Not really. The main application thread stack is trivially small. Other threads have stacks that could get a lot bigger, but I'll be surprised if you are chewing up 42MB that way.
If it is, what can I do to stop or
investigate the leak?
Since you already did a "spike solution" of testing sans UI and determining that is OK, I'd slowly reintroduce the UI and see when you start getting the problem. One likely candidate problem area would be updating the activity from a background thread, so you might turn that off and see what happens.
Since your problem isn't in the heap itself, my guess is that your problem is tied to bitmaps or other things that have lots of off-heap RAM usage. The camera in your avatar is another hint in this direction. :-) Make sure you are recycle()-ing your bitmaps and such, and see if that helps any.

Categories

Resources