Object pooling in ActionScript 3, step by step
Creating and discarding many short-lived objects makes the garbage collector work in bursts, and those bursts show up as stutter on phones. A pool keeps finished objects around so they can be reused.
A minimal pool
package pool {
public class Pool {
private var _items:Vector.<Object> = new Vector.<Object>();
private var _factory:Function;
public function Pool(factory:Function, prewarm:int = 0) {
_factory = factory;
for (var i:int = 0; i < prewarm; i++) {
_items.push(_factory());
}
}
public function take():Object {
return _items.length > 0 ? _items.pop() : _factory();
}
public function give(item:Object):void {
_items.push(item);
}
}
}
Using it
var bullets:Pool = new Pool(function():Object {
return new Bullet();
}, 40);
// firing
var b:Bullet = bullets.take() as Bullet;
b.reset(x, y, angle);
layer.addChild(b);
// when it leaves the screen
layer.removeChild(b);
bullets.give(b);
Rules that keep it safe
- Give every pooled class a
reset()method that puts it back into a clean state. Do not rely on the constructor. - Remove event listeners before returning an object, or it will keep reacting while it sits in the pool.
- Pre-warm the pool during a loading screen so the first burst of use does not allocate.
- Measure first. A pool adds bookkeeping, and it only pays off for objects created many times per second.