I have a couple quick questions. They all deal with 1 general topic, and one strategy may take care of everything, so I hope that its ok I put them under the same topic.
I have had trouble finding solid info on garbage collection, so would appreciate any help, I think perhaps I don't fully understand what I am reading in the MAT. Even if you can answer 1 question I would be super happy
What is the best strategy for finding memory leaks in Android? As best I can tell it is to get the Eclipse MAT, picking an object that isn't getting garbage collected (using the dominator tree, or whatever is easiest for you to find it with), and displaying the shortest merged paths to the gc of that object and find the furthest incoming reference to that object that you can control and killing that reference on destroy. This works to kill the references, but sometimes the object still doesn't get garbage collected
Is it good practice to null all of your handlers/runnables/threads/listeners on destroy? Some of these seem to stick around indefinitely if I don't, and sometimes even if I do.
What is the best way to ensure that a thread gets garbage collected, even if the reference is nulled (they seem to stick around sometimes)?
Why oh why can't I get the google analytics tracker to get garbage collected, even though it has no reference from my application at all. It seems to maintain a reference to my activity, so I think that might have something to do with my GC problems.
Thanks you!
The best strategy is to fully understand the implications of what you are doing from the beginning, and thus avoid memory leaks in the first place. See, for example, handling memory leaks in Java. Otherwise, that seems like a fine approach along with code inspection. Are you forcing a GC to prove that the object still isn't collected?
In general, no. This article has a good explanation as to why.
Don't hold any references to it? Follow standard coding practices as described above.
Don't know. But wouldn't you be using it throughout your application, so it doesn't really matter? Eventually Android will kill your whole process and reclaim the memory anyways.
Related
I'm using Firebase Performance Monitoring SDK (on Android, but will also on iOS) and for one particular use case it's hard to know whether a started Trace will ever be stopped. And given there is no apparent way how to cancel an already running trace, I figured I'd just start it every single time and then eventually stop it only under the right circumstances. (and leave intact otherwise).
Shall I expect issues? I figured the trace would not be logged if not stopped (that's what I need), but I'm scared of memory leaks and also some general resource waste.
I could also potentially clear the reference to the trace and hopefully let GC sweep it (provided Firebase doesn't store a reference to each running Trace)
If you start a trace but never stop it, a very small amount of memory will be leaked for that Trace object as it waits for you to stop it. It's probably not a big deal, but a leak is a leak. Clearing the reference when you would like to abandon the trace will allow it to be garbage collected.
I'm working on my first android application which is a big application though.. I have completed half of my app but what makes me worry is that the memory used by app.. Initially I faced the issues regarding out of memory exceptions.. I first started analyzing my app with MAT(Memory Analyzer Tool) of Android Studio, which was very difficult to track the memory usage.. My app would reach allocated space of 96mb and crash.. Then After Reading on internet i used Leak Canary which pointed out the static resources that was eating memory.. and now my app regularly gets Garbage collected but still i find the allocated space remains to be around 70 mb, Like my app starts with allocation of 30mb when i use app for about 2 min and come back to initial screen the allocated space is not same as initial... For beginners like me it is hard to track the memory usage to the core using MAT and is there a best approach or tool which would give me a clear picture of allocated space by objects.. Objects that are taking maximum space.. objects that are supposed get destroyed but not destroyed?? and retaining Image memory etc etc Thanks in advance
One of the main 'memory leakers' is the Bitmap. Sometimes when you load an image in a a View, it uses a lot of memory in the action. I used to recommend using libraries like Glide or Fresco which are better handling memory issues and have a lot of common features already implemented.
Also you could try to free resources for each activity in your onDestroy method.
Nevertheless, I would be great if you could give us a deeper overview of your project.
Regards.
There have been a few posts here related to memory management.
We have all been newbies at some point and thankfully experience and problems like these have proven to be excellent 'teachers'.
Like I have said in another post :
This will of course cause memory problems such as leaks, OOM and
unnecessary resource binding. There is absolutely no automatic way to
free up memory. You can not, under any circumstances, rely solely on
the Garbage Collector
Basically, you must ensure that you allocate only the required resources and deallocate them as soon as you know you wont need them anymore within the Lifecyce
I have wrote a more detailed explanation with code (that you can implement on your project) to deal with your memory issues which can be found here :
It can be found here
Regards,
I am working on a project and I keep seeing methods that nullify the views and listeners on every onDestroy(). I have even seen code that navigate the rootView and set every listener to null.
The original coder told me that he has done it that way to prevent leaks, but I think it is causing more harm to the VM. What do you think?
In my opinion, it is unnecessary. Once the activity is destroyed (i.e. onDestroy is called) then all the views and its related listeners are qualified for garbage collection.
However, make sure you are not treating anything static with activity and/or anything that is bound to activity's context (that includes Views too).
Most Android-related memory leaks are related to incorrect usage of event buses (forgetting to unsubscribe something), or from implicit reference to a context (public class Blah extends AsyncTask<?,?,?>), or static reference to the Activity (because who knows why, everybody knows that's a terrible idea).
Nulling out your views won't help you find any of that.
You can however use LeakCanary library which traces memory leaks for you automatically.
It may cause the GC to make the used memory be reuseable faster, but its not something i would do since its tedious and a waste of time.
If you want to prevent memory leaks you should used tools like LeakCanary or MAT or alike, or\and be well aware of diffrent Android components lifecycles and know what you are doing when using static variables. It is less likely that that guy avoided a memory leak, unless he references Android components in static fields (which is a bad idea anyway).
The Application class in android provides the methods onTrimMemory and onLowMemory. I don't really understand them (of course other than the obvious linguistic meaning). How might I implement the method onTrimMemory? What does it mean to trim memory? I am obviously looking for detail technical answers. Beyond emptying caches (should I do that?), there seems to be something more specific meant by trimming. How is that done in android? Is it an OS thing? Is it a system level thing? Should I worry about it? I would really love to know how to override it.
What does it mean to trim memory?
Let go of objects, so they can be garbage-collected.
Beyond emptying caches (should I do that?)
Yes.
there seems to be something more specific meant by trimming
Not really. Android is saying "hey, um, things are getting a big snug on system RAM, could you cut back" for lighter levels, and is saying "gee, this is a real nice process you got here — it would be a shame if we had to terminate it" for more severe cases.
Bear in mind that with Dalvik (and I assume ART), garbage collection can actually reduce your process' working set size (a.k.a., amount of system RAM you are using), and so by reducing your heap usage, you make it a bit less likely that Android will terminate your process while you are in the background.
How is that done in android?
Let go of objects, so they can be garbage-collected. Mostly, this should refer to caches. Anything else, you should be letting go of as your app runs, based on business rules. So, for example, while you could terminate background threads in onTrimMemory() (and therefore let go of any objects only reachable via those threads), there are probably better/earlier points in time to terminate those threads, if they are not adding any value.
Is it an OS thing?
I do not know what you consider an "OS thing" to be.
Is it a system level thing?
I do not know what you consider an "system level thing" to be.
Should I worry about it?
If you are manually maintaining a cache that might consume a lot of memory, ideally yes.
If you are using a third-party library that has a cache (such as an image-loading library), see whether they register for onTrimMemory() themselves. If not, you might see if the library has some API for you to tell it to reduce the cache, then call that yourself from onTrimMemory().
I have tried profiling my app, but found that TraceView isn't that user friendly, so I didn't find out why.
I think it may be because I'm allocating too much memory somewhere. So, in the attached image, I am getting these messages once every 2 seconds. Is this a sign of bad memory allocation?
Thank you very much,
Richard Hughes
No, I don't think that's a problem. GC is just freeing its memory as per its requirement.
To know more about memory allocations, please see following: http://codelog.dexetra.com/getting-around-android-memory-blues
They have explained this wonderfully.
May be this could also be happening because of a memory leak in your app. try to find it out. you can use MAT (plugin) for eclipse, its a bit difficult to understand at the first place, but as you will use it, you will understand, its a very good software to find memory leaks in ours apps.