
On Android, Garbage Collection Can Kill You - codeka
http://www.war-worlds.com/blog/2012/06/on-android-garbage-collection-can-kill-you
======
cluda01
You need to be really careful when using object pooling and carefully consider
two things: synchrony and lifecycle issues.

Synchrony issues occur when sharing an object pool among multiple threads. If
you're sharing an object pool and using an unsafe data structure you will run
into concurrent modification exceptions. Another issue could also be that
using a thread safe data structure (or more simply a syncrhonized method) will
lead to huge performance degradations because it is a central point of
contention. A third issue with object pools is that if you have multiple
threads using an object pool it might fill up your entire heap with cached
objects.

The lifecycle issues come into play when you ask the question, "Who returns
the object to the pool?" For example you could have 1 thread passing an object
to another thread and then returning the object to the pool. If not considered
you could run into a possibility where 2 different threads are operating on an
object as if they are the sole owners leading to unexpected results.

------
ajross
FTA: " _A quick look at the output from ddms shows I was allocating tens of
thousands of Colour, Vector2 and Vector3 objects per image_ "

And this is the fault of the garbage collector? Doing per-primitive ops by
allocating heap blocks is a disaster, sorry. No one doing HPC does that. This
won't run well anywhere, though obviously a desktop machine is going to give
you a lot more freedom before you see frame rate problems.

~~~
kevingadd
It's the fault of the garbage collector because the JVM provides no sane
alternative (like, say, structs, or packed object arrays...).

If there's Only One Way To Do It, that One Way should not cause the garbage
collector to fall over and choke. It sounds like the desktop JVM handles it
just fine, in comparison.

~~~
ww520
Why not just pre-allocate the objects and reuse them?

~~~
kevingadd
Have fun getting that pattern right by hand. The language isn't doing anything
to help you.

Make sure you release the instances back to the pool on every exit path, but
don't release them if you let a reference escape into another scope.

Have fun debugging the issues that crop up when you accidentally release an
instance that's still being used back into the pool.

Have fun hunting down that one code path that isn't returning instances to the
pool, and as a result is draining the pool down to 0 and causing you to gain
nothing from it.

~~~
ww520
Didn't people do all that before the advent of GC? People seemed to manage
resources just fine.

------
fragmede
On Google App Engine, Over Quota can kill you:

Over Quota This application is temporarily over its serving quota. Please try
again later.

is all I get right now from the link.

~~~
reginaldo
Cache link:
[http://webcache.googleusercontent.com/search?sourceid=chrome...](http://webcache.googleusercontent.com/search?sourceid=chrome&ie=UTF-8&q=cache:http%3A%2F%2Fwww.war-
worlds.com%2Fblog%2F2012%2F06%2Fon-android-garbage-collection-can-kill-you)

~~~
astrodust
It's ironic that we need to use Google to cache a Google site that's over-
quota, right?

------
lucian1900
Actually, Dalvik's GC just plain sucks, too.

Clojure has a similar problem: works fine on desktop JVMs, but even
initialising it takes many seconds on Dalvik.

~~~
vetinari
Your laptop has 10x memory bandwidth of top-end Android phones (and 20x of
midrange phones). Double the numbers for desktop.

In short, mobile devices are different than laptops/desktops. If you threat
them same, your application will suck.

~~~
ajross
Closer to 5x than 10x. Don't do the math based on the clock speed, look at the
cycle times (which are mostly the same between DDR3 2000 and LPDDR2 533). A
desktop or laptop CPU (unless by "laptop" you mean "netbook" -- laptops based
on mainstream CPU cores have the same memory interconnect as desktops) will
have two 64 bit DRAM channels, a typical phone will have a single 32 bit
channel.

------
freehunter
I guess from the headline, I expected more than what everyone already knows:
garbage collection takes up processor time, especially on unoptimized code. I
was expecting something new.

~~~
aidenn0
Ah yes, but the article claims that Dalvik has a poor gc.

------
jemfinch
Is this really a credible complaint? Someone who wrote this:

    
    
        public int hashCode() {
            return new Double(x).hashCode() ^ new Double(y).hashCode();
        }
    

does not seem to have the requisite understanding of how things to work to
declare the inferiority of a widely used garbage collector.

~~~
swah
Can you explain what is obviously wrong in this code?

~~~
jemfinch
You don't need to allocate a new double to call hashCode on it. You can just
call hashCode on the double you already have.

Out of curiosity, what language background are you coming from that this isn't
obvious?

~~~
swah
Python mostly.

The constructor for Double is:

    
    
        Double(double value)
    

I thought only 'Double' had the class methods, not 'double'.

~~~
jemfinch
You're right, I forgot that there's such a distinction in Java.

------
stevenwei
It's a bit strange to me that one of the recommended optimizations is to
create fewer objects in a programming language that is heavily object
oriented.

~~~
reeses
I remember the last time I got involved in one of these discussions, where the
same give-and-take was brought up:
[https://groups.google.com/d/msg/comp.lang.ruby/vWcRBbg8VGE/0...](https://groups.google.com/d/msg/comp.lang.ruby/vWcRBbg8VGE/0OUuQmCMuFcJ)

------
chrisreed212
It's not GC per se, it's that the Dalvik JVM doesn't do some analysis and note
that the object that you create to pass to a method which doesn't escape it
can be created on the stack as it is guaranteed not to exist beyond the
calling method.

