Anyone here know if pooling is more efficient than Android's GC for small objects used often?
That depends on how you measure "efficient", "small", and "often".
Object pooling is used in several places within Android itself, such as:
the whole Adapter
framework for AdapterView
(ListView
and kin) is designed around object pools, this time for relatively heavyweight objects (e.g., a ListView
row can easily be tens of KB)
SensorEvent
objects are recycled, this time for lightweight objects used potentially dozens of times per second
AttributeSet
objects are recycled, as part of View
inflation
and so on.
Some of that was based on early versions of Dalvik in early versions of Android, when we were aiming at under 100MHz CPUs with a purely interpreted language and a fairly naïve GC engine.
However, even today, object pooling has one big advantage beyond immediate performance: heap fragmentation.
Java's GC engine is a compacting garbage collector, meaning that contiguous blocks of free heap space are combined into much larger blocks. Dalvik's GC engine is a non-compacting garbage collector, meaning that a block that you allocate will never become part of a larger block. This is where many developers get screwed with bitmap management -- the OutOfMemoryError
they get is not because the heap is out of room, but that the heap has no block big enough for the desired allocation, due to heap fragmentation.
Object pools avoid heap fragmentation, simply by preventing the pooled objects from getting garbage collected again and not allocating new objects for the pool very often (only if the pool needs to grow due to too much simultaneous use).
Game developers have long used object pooling in Android, stemming from back when Android's garbage collection was non-concurrent, "stopping the world" when GC was conducted. Now, most Android devices uses a concurrent garbage collector, which eases the pain here some.
So, object pooling is definitely still a relevant technique. Mostly, though, I'd view it as something to employ as a reaction to a detected problem (e.g., Traceview showing too much time in GC, Traceview showing too much time in object constructors, MAT showing that you have plenty of heap but you get OutOfMemoryErrors
). The exception would be game development -- game developers probably have their own heuristics for when pooling is still needed with modern Android devices.