Click or drag to resize
DigitalRuneHow To: Enable Resource Pooling for an Object

The resource pool implementation in the DigitalRune Base (see ResourcePoolT) can be used to create a pool of objects that can be reused at runtime.

When we start to design a class library we usually don’t care about resource pooling. Only when the major parts of the API and the internal algorithms are done we start to measure performance and profile memory usage. When we started optimizing DigitalRune Geometry and Physics we realized that some objects needed to be pooled in order to avoid garbage on Xbox 360 and Windows Phone 7. So a few types had to be made reusable.

The following pattern has proven very handy for turning a normal object into a pooled object.

Making an object reusable

Let’s assume we have the following type:

C#
public class MyObject
{
  public MyObject(object param1, object param2)
  {
    // Initialize instance.
    ...
  }

  // Field, properties, methods, etc.
  ...
}

To make the type reusable we add a local resource pool and add Create/Recycle methods:

C#
public class MyObject
{
  private static readonly ResourcePool<MyObject> Pool =
    new ResourcePool<MyObject>(() => new MyObject(), null, null);

  private MyObject()
  {
  }

  public static MyObject Create(object param1, object param2)
  {
    var obj = Pool.Obtain();

    // Initialize instance.
    ...

    return obj;
  }

  public void Recycle()
  {
    // Clean up instance.
    ...

    Pool.Recycle(this);
  }

  // Field, properties, methods, etc.
  ...
}

The new version is very similar to the first version. The original constructor is removed. This way we automatically get compiler errors in all places where the type is used. That’s great because now we know where we need to add the Create/Recycle calls.

Instead of creating an object with

C#
var myObject = new MyObject(param1, param2);

we now need to write

C#
var myObject = MyObject.Create(param1, param2);

That’s not too bad - the usage is very similar. The caller does not need to have a reference to the resource pool from where the object is taken. Note also that the default constructor is private. This prevents others (or ourselves) from accidentally creating new instances and bypassing the resource pooling.

The owner of the new object can at some point call

C#
myObject.Recycle();

to reset and recycle the instance. Again, the caller does not need to have a reference to the actual resource pool which is very handy.

So overall, this pattern has proven to be very useful. The object is now reusable and the impact on existing code is minimal.

See Also