Design Pattern: Object Pool
Re-usable instances of a Class.
Type: Creational.
An object pool essentially keeps a set of re-usable instantiated objects in a cache (pool) where each is put back and reset after use. This is to avoid the object creation/destruction overheads.
For example, a good candidate for such a pattern is a large and/or complex class that is constantly being instantiated and creates a performance bottleneck because of this.
Stateful objects must be reset when released back into the pool and behaviour must be defined when a process tries to fetch an object from an empty pool (e.g.: throw exception, create instances, wait...).
C++11
In C++ object pooling can be easily achieved by using std::unique_ptr
and a custom deleter. Pool release is then auto-magically done even when calling std::unique_ptr.reset()
on the pooled object pointer.
class Deleter {
public:
explicit Deleter( std::weak_ptr<ObjectPool*> pool ) :
_pool( pool )
{}
void operator()( Object *ptr ) {
if( auto pool_ptr = _pool.lock() ) {
/* Pool exists so add pointer back to pool */
( *pool_ptr.get() )->release( std::unique_ptr<Object>{ ptr } );
} else {
/* Pool has been destroyed so default deleter is used instead */
std::default_delete<Object>{}( ptr );
}
}
private:
std::weak_ptr<ObjectPool*> _pool; /* non-owning smart pointer */
};
Java
Since Java is a Garbage Collected language the pool's object acquisition must be explicit and disposal must be used to "return" the borrowed object to the pool.
Generally, this pattern should be avoided as memory allocation and garbage collection in modern JVMs is very cheap for short lived objects. Exceptions are when object creation cost is very high (threads, network or db connections...).