Is it normal and "ok" for a static instance of a class to be GC'ed so much? I built a subset of graphs and once I execute my graphing option in my app, I see the GC and my static instance get wiped.
I'm not having issues, just looking for some learning feedback. This trace test was done on my Galaxy Nexus.
This is normal because your app (a content provider perhaps?) is only kept running by the OS as long as necessary.
Let android do its thing.
Related
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:
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"
Noob question!
My whiteboard/drawing app runs fine, using a combination of simple image views and bitmaps with me rendering a path to a bitmap and copying over as needed. I have it multitasking on my ICS Transformer without problems. However, if I exit the app with the Back button and then run it again, it fails; I get a memory error on the second run when I try to draw something.
Out of memory on a 4096016-byte allocation
Although sometimes I don't get that and it runs a second consecutive time. When I run it a third time, it works, and the fourth, again it Out-of-memory's.
What manual cleanup do I have to do when an Android app exits? Should I remove all created objects and bitmaps and paths and listeners and stuff?
Looks like you have a memory leak. Make sure you follow recommendations provided here. Often Memory Analyzer Tool is very useful in such cases. Here is a video how to use it.
When starting my Android wallpaper application, the application consumes slowly more and more memory. I am trying to figure out why this is happening and haven't been very successful yet.
At one time I got an information in logcat as "Low memory no more background process". At this time my app quit for a few seconds and restart it again.
Am calling two native functions repeatedly on the background to draw the wallpaper. Is this problem?
Please read: http://android-developers.blogspot.co.uk/2009/01/avoiding-memory-leaks.html
You are probably using static members and reusing widgets with old Context and that makes android unable to free the memory of old contexts that expired long ago.
Don't use static members when you can avoid it
Under no conditions should you set a widget to public/default static always use private
Use final as much as you can
Do more research online
my android application works well but it's performance(speed) is slow. In my logcat i saw frequent garbage collection operation like
11-02 15:07:20.647: DEBUG/dalvikvm(12571): GC freed 295 objects / 38448 bytes in 93ms
Is this the reason for low performance?? How can i improve my applications performance???
anybody please help
If you use the emulator don't worry - it is slow by itself. GC is not responcible for this i think, 93 ms is time you won't even notice. So try your application at the real phone and if there are preformance issues - use the profiler.
Your application performance in terms of user interface and memory is quite related.
In this case 93ms means that your device could be dropping about 6 frames in the ideal scenario. If the GC is executed often this could be a problem.
The Android ART/Dalvik virtual machine is a version of the Java Virtual Machine where the Garbage Collector implementation is based on generations. This means that your application process has a heap associated separated by different generations where the GC is going to act once a generation is full. You can think of these generations as buckets or arrays of memory.
Once a generation is full the Android virtual machine will start the garbage collector process. As the Android virtual machine can not collect and fragment your application heap while the app process is running the garbage collector event will stop all the threads in your app while the garbage collector is working. That's why your application can be dropping frames if the app garbage collector is invoked so repeatedly.
Here you have an example:
Last week I discovered my app was leaking memory. I discovered this because after 20 minutes using my app I noticed the UI was performing really slow. Closing/opening an activity or scrolling a RecyclerView was really slow. After monitoring some of my users in production using http://flowup.io/ I found this:
The frame time was really really high and the frames per second really really low. You can see that some frames needed about 2 seconds to render :S.
Trying to figure it out what was causing this bad frame time/fps I discovered I had a memory issue as you can see here:
Even when the average memory consumption was close to the 15MB at the same time the app was dropping frames.
That's how I discovered the UI issue. I had a memory leak in my app causing a lot of garbage collector events and that's was causing the bad UI performance because the Android VM had to stop my app to collect memory every single frame.
Looking at the code I had a leak inside a custom view because I was not unregistering a listener registered into a Android Choreographer instance. After releasing the fix, everything became normal :)
If your app is dropping frames due to a memory issue you should review two common errors:
Review if your app is allocating objects inside a method invoked multiple times per second. An example could be creating new instances of an object inside a onDraw custom view method.
Review if your app is registering an instance into the Android SDK but not releasing it. Registering a listener into a bus event could also be possible leak.
Disclaimer: The tool I've been using to monitor my app is under development. I have access to this tool because I'm one of the developers :) If you want access to this tool we will release a beta version soon! You can join in our web site: http://flowup.io/.
If you want to use different tools you can use: traveview, dmtracedump, systrace or the Andorid performance monitor integrated into Android Studio. But remember that this tools will monitor your connected device and not the rest of your user devices or Android OS installations.