Is manual garbage collection in Android necessary? - android

While developing reasonably complex applications (e.g. accessing external resources such as files, database, network connections) on Android platform is it necessary to handle the Garbage Collection? Or should I let Android take care of GC all the time?
So does Garbage Collector relives an Android programmer from all burden of freeing memory?
If not, then can anybody explain with a practical example why is it so?

In general, GC helps programmers avoid many problems, but it is not a cure-all. As a programmer using a GC'ed system, you have two main things to worry about in terms of the allocation lifecycle:
Dropping references (e.g. setting variables to null) when objects are no longer needed. Failing to do so could result in a memory leak.
Explicitly managing non-memory resources, such as open files. The objects representing these things typically arrange to free up the resources when the objects get GC'ed, but as the programmer you may have a better idea about when the resource is truly unneeded. So, it is in your best interest to (say) explicitly call close() on an InputStream instead of just letting the GC clean it up long after it's no longer needed.

Related

Android studio 3 profiler. How to identify cause for objects stuck in the heap

I am trying to understand how to identify and solve memory leaks.
I know how to deal with general memory leak issues. Leaked activities, inner classes etc. They are usually quite easy to identify. By dumping the heap and look for references.
Right now i am stuck with something probably very simple. Some very small object are stuck in the heap and i just cannot find any references to it in the heap explorer. See image below.
As you can see there is a MatchOddsAdapterStickyHeader instance and an array containing these instances.
My question is why these objects are still in the heap.?
The MatchOddsAdapterStickyHeader[] instance only contains references to a single MatchOddsAdapterStickyHeader instance. And each single MatchOddsAdapterStickyHeader only have a string. I just don't understand why GC did not clean up this objects. Both object have no references to any alive object. And yes i forced GC. makes no difference.
I know its only a few bytes. And it doesn't really give a problem in my app, but still i want to have a 100% memory leak free app if possible.

Importance of the dispose method (libgdx)

I'm just getting started with Android Game Development and I'm testing the libgdx Framework at the moment. I was just wondering what the importance of the dispose() method is and why it is necessary to dispose of every object there? Just to save resources?
Appreciate it.
Java is a "managed language". This means that everything (e.g. instances of classes or arrays) you use in your application automatically gets destroyed when you no longer use it. This is done by the "garbage collector". So, when you create e.g. an array (float[] arr = new float[1000];) then you allocate memory, but you never have to free that memory yourself because the garbage collector will do that for you when you no longer use the array (arr).
In some cases, however, the garbage collector can't know how to automatically free something for you. For example, when you allocate some space in video memory (VRAM) then you don't have access to that memory directly, but instead use the graphics driver to use that memory. For example (pseudo code):
byte[] image = loadImageFromDisk();
int vramId = graphicsDriver.allocateMemory(image.length);
graphicsDriver.copyToVRAM(vramId, image);
image = null;
...
// At this point the garbage collector will release the memory used by "image".
// However, the allocated VRAM still contains a copy of the image, so you can still use it.
...
graphicDriver.showImageOnScreen(vramId);
...
// The garbage collector can't free the VRAM though, you need to manually free that memory.
...
graphicsDriver.releaseMemory(vramId);
So, practically, there are two kind of resources in this case.
Resources that will be automatically released by the garbage collector. Let's call those: managed resources.
Resources that can't be automatically released by the garbage collector. Let's call those: native resources.
As you probably can imagine, libgdx uses quite alot of native resources behind the scenes. To properly manage those resources libgdx contains the Disposable interface. Every class that implements this Disposable interface uses (directly or indirectly) native resources that can't be released automatically by the garbage collector. Therefor you need to manually call the dispose methods on those classes if you no longer need them.
Not calling the dispose method can potentially result into problems with native resources. E.g. you might run out of available video memory or alike, causing your application to crash or alike. This is most commonly referred to as a "memory leak".

How does using singleton patterns in Android impact memory usage?

I'm thinking about using singleton patterns for adapters and helpers in an Android app that I'm building, but I'm not too familiar with Java's garbage collecting and how static attributes (eg static FooBar instance) impact memory usage.
Will it have a big enough impact in Android apps that I should avoid using it?
Depends on what you mean by "impact memory usage". An object isn't larger or smaller just because there is one instance of it enforced by a singleton pattern. In that sense there's no difference.
If it means you definitely have at most one copy of an object in memory instead of several, yes it could help.
Usually what people mean though, is, how long does the singleton live? does it stick around taking up memory when the app is in the background?
A static member is attached to an instance of its Class which is in turn attached to its ClassLoader. So the singleton lives as long as the ClassLoader. It turns out in Android that the app's ClassLoader goes away in onDestroy, not onPause, so a singleton implies you hold on to the memory even when the app is in the background.
As others have said, it depends. The case where it could be bad is if the singleton is holding references to objects that could otherwise be garbage collected. If there are a lot of references in the object, or references to large objects, you could be using memory you don't need. You could work around it by using weak references, but then you have to have code to recreate the objects when needed if they get garbage collected. You could not use the singleton pattern, which would allow things to get garbage collected (at least potentially), but at the expense of creating and throwing away objects. The best solution depends on the details of the object and its usage. One thing to always avoid is holding on to a reference to a UI object, such as a View.

How to release memory in android to avoid memory leak

While going through the android developer site i found this .
it says to avoid memory leak we should release resources in onStop()but how to do so.
Basically any objects that are properly nulled are considered released and their memory can be reclaimed by the OS. Your question is too general and it's hard to offer a exhaustive list of methods, but you should generally be aware of these:
Stop/close any services/files/connections that you no longer need
Do NOT store any Drawable in any static Object, Drawables hold references to their owner View's which hold references to their owner Activity's, so if you hold on to any Drawable you will hold onto a lot of objects/memory unnecessarily
For an utility app, you probably needn't worry about memory; but for apps that use lots of Bitmaps, you should have a deep understanding of Bitmap management and how Bitmaps are used in your app in order to manage them effectively
There are a few notorious examples of memory hogs, with media (audio/video) and large bitmaps being the biggest memory hogs. Most things are taken care of by removing all pointers to them and letting GC have its way with them. Bitmaps, however, can be recycled more immediately by using:
if (yourBitmap != null) {
yourBitmap.recycle();
youBitmap = null;
}
Your media should be stopped and de-referenced. But it should be stopped in onPause(), and not left until onStop().

Generic Android Garbage Collection

I don't want to create a vague question so I will try to make this as clear as possible (Going to try my best).
I know garbage collection has been a grey area in programming for a very long time. I am not certain with the case of android or other mobile phones.
What I know of garbage collection in android:
It collects class system class ojbects(Made by correction from an answer).
Edit* "GC collects activity items only once the activity is destroyed. Activity lifecycle is driven by its attributes in the manifest, also by the flags of the intent that that launched it." – Seva Alekseyev . As commenter said.
You may force a garbage collection using "System.gc()" although this is not recommended as it may delete something important class item.
Now I obtained this information from stackoverflow(Now knowing that it is no longer a grey area for garbage collection)
Going to my question:
How do you get this information about the process or generic information(book, internet article, etc.) about garbage collection from?
If there is not answer for question 1 what are the other ways or methods that developers should be reminded when developing applications requiring the constant use of memory?
I'm not sure your information is correct.
It collects class system classes.
No. It collects instances of objects that are no longer reachable from any of the system roots. System roots include any static reference, any reference from a thread's active stack frame, any active synchronization monitor, and anything held by a native piece of code (global or local). An object is considered live (and hence cannot be reclaimed) if there is a path from it to a root tracing the reference graph backwards. Any object that doesn't not have a path to a root can be reclaimed by the garbage collector. Classes are referenced by a ClassLoader and are never reloaded and hence are not reclaimed by the system unless that ClassLoader is collected and all instances of those classes are collected. So Android never collects class system classes because that ClassLoader is never collected.
It collects items from activity "only" if android manifest file states that the activity is either hasNoHistory or singleTop
No. An activity is nothing more than an instance of an object. And when the reference to the activity is gone so goes all of the references it pointed to unless some other root points to that object. By setting singleTop="true" you are only telling Android to instantiate a single instance of this activity, and all intents sent will be handle by that single instance. It doesn't have any impact on GC. When an activity looses its path to a root it will be reclaimed regardless of what the settings on that activity were.
You may force a garbage collection using "System.gc()" although this is not recommended as it may delete something important class item.
No Garbage collection algorithms do not delete any live object. Under your definition above it implies GC can collect an object you were using which is incorrect. If it did that's a big bug. That is also the beauty of Garbage Collection algorithms in that they are guaranteed to clean up garbage perfectly. If you are running out of memory the programmer has forgotten to remove a reference or you are being careless with your use of memory. The reason you aren't suppose to call System.gc() is that you/your program has no clue when the best time is to reclaim memory. The garbage collector is trying to maximize the ratio of (the time your program runs) vs. (the time it spends collecting garbage). It keeps very detailed statistics and makes estimations about when its a good time to run garbage collection vs simply allocating more memory.
It's like cleaning your house. You can't clean at all times because it makes doing things take longer sometime you have to let it get dirty (Like cooking). However, if you never clean your house it can take all day to clean it. So there is a balance that you must strike between how dirty can it become before cleaning it up takes longer than performing the task.
This is why you shouldn't calculate/guess/force GC in your program because Android has already implemented it for you, and will do a better job than you can ever hope to.
What does this mean for you the developer?
Let Android handle when GC should run.
Clean up references to help the GC know when something can be reclaimed. Be very careful about static references, and never allow a static to hold a reference to an activity, service, etc to one.
Don't allocate lots of small amounts of short lived memory. This will force more GC time to clean up. By allocating memory conservatively you are by definition helping that ratio.
Most of the time GC is very hands off. The only problems developers get into is not establishing boundaries for long living objects vs. UI objects. If a long living objects has a reference back to the UI that's a place you'll have to unregister or else you'll leak memory. It's ok for the UI to hold references to long living objects, but not the other way around.
The real issue with Android is how much you make the garbage collector work. If you keep the amount of memory you are using small then the garbage collector doesn't have big jobs it has to do. That doesn't mean you should reuse objects or create object pools, etc. But, you should be aware of what statements are creating memory, and how long those objects live for.
There are volumes of information on Garbage collection in general and particularly Java's Concurrent Mark and Sweep garbage collector. Android's garbage collector is not as performant, but it's pretty darn good. Most of the time I don't worry about GC unless there is a problem so it's mostly hands off.
And garbage collection isn't a grey area. It's very much well understood, and the industry has expanded the field quite a bit since Java was introduced in 1994.

Categories

Resources