Garbage collector in Android

JavaAndroidGarbage Collection

Java Problem Overview


I have seen many Android answers that suggest calling the garbage collector in some situations.

Is it a good practice to request the garbage collector in Android before doing a memory-hungry operation? If not, should I only call it if I get an OutOfMemory error?

Are there other things I should use before resorting to the garbage collector?

Java Solutions


Solution 1 - Java

For versions prior to 3.0 honeycomb: Yes, do call System.gc().

I tried to create Bitmaps, but was always getting "VM out of memory error". But, when I called System.gc() first, it was OK.

When creating bitmaps, Android often fails with out of memory errors, and does not try to garbage collect first. Hence, call System.gc(), and you have enough memory to create Bitmaps.

If creating Objects, I think System.gc will be called automatically if needed, but not for creating bitmaps. It just fails.

So I recommend manually calling System.gc() before creating bitmaps.

Solution 2 - Java

Generally speaking, in the presence of a garbage collector, it is never good practice to manually call the GC. A GC is organized around heuristic algorithms which work best when left to their own devices. Calling the GC manually often decreases performance.

Occasionally, in some relatively rare situations, one may find that a particular GC gets it wrong, and a manual call to the GC may then improves things, performance-wise. This is because it is not really possible to implement a "perfect" GC which will manage memory optimally in all cases. Such situations are hard to predict and depend on many subtle implementation details. The "good practice" is to let the GC run by itself; a manual call to the GC is the exception, which should be envisioned only after an actual performance issue has been duly witnessed.

Solution 3 - Java

Out of memory in android application is very common if we not handle the bitmap properly, The solution for the problem would be

if(imageBitmap != null) {
    imageBitmap.recycle();
    imageBitmap = null;
}
System.gc();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3;
imageBitmap = BitmapFactory.decodeFile(URI, options);
Bitmap  scaledBitmap = Bitmap.createScaledBitmap(imageBitmap, 200, 200, true);
imageView.setImageBitmap(scaledBitmap);

In the above code Have just tried to recycle the bitmap which will allow you to free up the used memory space ,so out of memory may not happen.I have tried it worked for me.

If still facing the problem you can also add these line as well

BitmapFactory.Options options = new BitmapFactory.Options();
options.inTempStorage = new byte[16*1024];
options.inPurgeable = true;

for more information take a look at this link

https://web.archive.org/web/20140514092802/http://voices.yahoo.com/android-virtual-machine-vm-out-memory-error-7342266.html?cat=59


NOTE: Due to the momentary "pause" caused by performing gc, it is not recommended to do this before each bitmap allocation.

Optimum design is:

  1. Free all bitmaps that are no longer needed, by the if / recycle / nullcode shown. (Make a method to help with that.)

  2. System.gc();

  3. Allocate the new bitmaps.

Solution 4 - Java

If you get an OutOfMemoryError then it's usually too late to call the garbage collector...

Here is quote from Android Developer:

> Most of the time, garbage collection > occurs because of tons of small, > short-lived objects and some garbage > collectors, like generational garbage > collectors, can optimize the > collection of these objects so that > the application does not get > interrupted too often. The Android > garbage collector is unfortunately not > able to perform such optimizations and > the creation of short-lived objects in > performance critical code paths is > thus very costly for your application.

So to my understanding, there is no urgent need to call the gc. It's better to spend more effort in avoiding the unnecessary creation of objects (like creation of objects inside loops)

Solution 5 - Java

It seems System.gc() do not work on Art Android 6.0.1 Nexus 5x, So I use Runtime.getRuntime().gc(); instead.

Solution 6 - Java

Generally speaking, you should not call GC explicitly with System.gc(). There is even the IO lecture (http://www.youtube.com/watch?v=_CruQY55HOk) where they explain what the GC pauses log mean and in which they also state to never call System.gc() because Dalvik knows better than you when to do so.

On the other hand, as mentioned in the above answers already GC process in Android (like everything else) is sometimes buggy. This means Dalvik GC algorithms are not on par with Hotspot or JRockit JVMs and might get things wrong on some occasions. One of those occasions is when allocating bitmap objects. This is a tricky one because it uses Heap and Non-Heap memory and because one loose instance of bitmap object on the memory-constrained device is enough to give you an OutOfMemory exception. So calling it after you don't need this bitmap any more is generally suggested by many developers and is even considered good practice by some people.

A better practice is using .recycle() on a bitmap as it is what this method is made for, as it marks native memory of the bitmap as safe to delete. Keep in mind that this is very version dependent, meaning it will generally be required on older Android versions (Pre 3.0 I think) but will not be required on later ones. Also, it won't hurt much using it on newer versions either (just don't do this in a loop or something like that). New ART runtime changed a lot here because they introduced a special Heap "partition" for big objects but I think it will not hurt much to do this with ART ether.

Also one very important note about System.gc(). This method is not a command that Dalvik (or JVMs) are obligated to respond to. Consider it more like saying to Virtual machine "Could you please do garbage collection if it's not a hassle".

Solution 7 - Java

My app manage a lot of images and it died with a OutOfMemoryError. This helped me. In the Manifest.xml Add

<application
....
   android:largeHeap="true"> 

Solution 8 - Java

Best way to avoid OOM during Bitmap creation,

http://developer.android.com/training/displaying-bitmaps/index.html

Solution 9 - Java

I would say no, because the Developer docs on RAM usage state:

>...
>GC_EXPLICIT
>
An explicit GC, such as when you call gc() (which you should avoid calling and instead trust the GC to run when needed).
>
>...

I've highlighted the relevant part in bold.

Have a look at the YouTube series, Android Performance Patterns - it will show you tips on managing your app's memory usage (such as using Android's ArrayMaps and SparseArrays instead of HashMaps).

Solution 10 - Java

Quick note for Xamarin developers.

If you would like to call System.gc() in Xamarin.Android apps you should call Java.Lang.JavaSystem.Gc()

Solution 11 - Java

There is no need to call the garbage collector after an OutOfMemoryError.

It's Javadoc clearly states:

> Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

So, the garbage collector already tried to free up memory before generating the error but was unsuccessful.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionhpiqueView Question on Stackoverflow
Solution 1 - JavasteveView Answer on Stackoverflow
Solution 2 - JavaThomas PorninView Answer on Stackoverflow
Solution 3 - JavayogeshView Answer on Stackoverflow
Solution 4 - JavaAndreas DolkView Answer on Stackoverflow
Solution 5 - JavacmicatView Answer on Stackoverflow
Solution 6 - JavaIgor ČordašView Answer on Stackoverflow
Solution 7 - JavaKlykooView Answer on Stackoverflow
Solution 8 - JavaprabhuView Answer on Stackoverflow
Solution 9 - JavaFarbod Salamat-ZadehView Answer on Stackoverflow
Solution 10 - JavaDenis GordinView Answer on Stackoverflow
Solution 11 - JavaChristian SeifertView Answer on Stackoverflow