Nader Al-Naji
Nader Al-Naji

Reputation: 47

how to stop the garbage collector from being called in android

I'm writing an app that generates a fair amount of garbage but nowhere near enough to hit the memory limit. That is, even though garbage is generated, there is no need to collect garbage. However, in spite of this, and in spite of the fact that a very small percentage of the total memory available is being used, the garbage collector is constantly being called and lagging my application.

As you can see from this output, I'm using only 2% of my available memory and yet the garbage collector is constantly running:

12-22 04:36:08.219: D/dalvikvm(12033): WAIT_FOR_CONCURRENT_GC blocked 61ms
12-22 04:36:08.359: D/dalvikvm(12033): GC_CONCURRENT freed 1012K, 98% free 11865K/405196K, paused 4ms+13ms, total 73ms
12-22 04:36:08.359: D/dalvikvm(12033): WAIT_FOR_CONCURRENT_GC blocked 38ms
12-22 04:36:08.479: D/dalvikvm(12033): GC_CONCURRENT freed 1020K, 98% free 11862K/405196K, paused 3ms+13ms, total 66ms
12-22 04:36:08.479: D/dalvikvm(12033): WAIT_FOR_CONCURRENT_GC blocked 36ms
12-22 04:36:08.649: D/dalvikvm(12033): GC_CONCURRENT freed 1015K, 98% free 11863K/405196K, paused 2ms+16ms, total 78ms
12-22 04:36:08.649: D/dalvikvm(12033): WAIT_FOR_CONCURRENT_GC blocked 66ms
12-22 04:36:08.789: D/dalvikvm(12033): GC_CONCURRENT freed 1017K, 98% free 11861K/405196K, paused 2ms+13ms, total 66ms
12-22 04:36:08.789: D/dalvikvm(12033): WAIT_FOR_CONCURRENT_GC blocked 58ms

Avoiding this unnecessary garbage collection entirely will make or break my app.

Why is the garbage collector running if I have plenty of free memory? Is there any way I can keep the garbage collector from running until absolutely necessary? I should also mention I'm running on a rooted phone.

Thanks!

Edit: Ugh.. I've been trying to eliminate all garbage using factories and various techniques but there's still a fair amount being generated and I think it's due to some string concatenation of the form s1 + s2 + s3 . I've converted such expressions into forms where I can save references to each component but I'm not sure it's air-tight. Do you see any garbage being generated by the following lines?

String ss1 = input.substring(m, m+k1);
String ss2 = ss1 + possible_perturbations1.charAt(p1);
String ss3 = input.substring(m+k1+1, m+k2);
String ss4 = ss2 + ss3;
String ss5 = ss4 + possible_perturbations2.charAt(p2);
String ss6 = input.substring(m+k2+1, m+i+1);
String current_str = ss5 + ss6;

allStrs.add(ss1);
allStrs.add(ss2);
allStrs.add(ss3);
allStrs.add(ss4);
allStrs.add(ss5);
allStrs.add(ss6);
allStrs.add(current_str);

A couple notes: the remove functions of most of the standard library containers generate garbage, as do most binary operations between objects that generate temporary variables such as Strings, Integers, Doubles, etc... Obvious to most, I guess, but still good to make clear.

Upvotes: 3

Views: 6129

Answers (3)

fhucho
fhucho

Reputation: 34530

It's normal for Android's GC that it runs even if the app uses just a fraction of available heap memory.

One possible reason of that: lots of couple of milliseconds long GC runs are better than one big several seconds long GC run (which would be noticable by the user).

How are you creating the garbage? In most cases, you can simply create only a fixed number of objects and reuse them (perhaps via an object pool).

If you're 100% sure that you know what you're doing and that no better solutions exist, you can keep references to the garbage objects to prevent the GC from removing them. But you almost certainly don't want to do this.

Update:

Usually, you shoud avoid String concatenation (every concat creates new object) and use StringBuilder instead:

String abc = a + b + c; // Wrong
String abc = new StringBuilder(a).append(b).append(c).toString(); // Right

Upvotes: 0

ndsmyter
ndsmyter

Reputation: 6605

The garbage collector will run whenever it wants. There is no way in stopping the garbage collector. There is even no real way to call the garbage collector, you only ask if the garbage collector would feel like running, but even then there is a chance it will not run.

The garbage collector will also not only run when you are out of memory, it will always try to prevent an "OutOfMemory" exception. As far as I know, the GC will run on given intervals and have a look at the variables that aren't needed in scope anymore.

As Sahil Mahajan Mj already said, the best way is to reuse your object. This will not prevent the Garbage Collector from running (as mentioned, it will run anyway), but it will make sure the GC has not a lot to do (which saves time).

Upvotes: 0

Sahil Mahajan Mj
Sahil Mahajan Mj

Reputation: 11141

Without your code, its not easy to say, why the garbage collector is being called, its not an error, but its the duty of GC to collect memory chunks if they are free.

Garbage collector activates when you have objects that were created and are not used anymore.

The best way of not be lagged by the GC is to avoid the need to collect garbage all the time. You could for example reuse objects instead of nulling them and creating new ones.

But FYI, you cant stop Garbage Collector from running, and dont even try to.

Upvotes: 3

Related Questions