|
|
|
Back to newsletter 033 contents
Should I use object pooling to avoid objects with a short life?
In the early JVMs, the answer to this was clear cut "yes". But now, even the embedded and J2ME
JVMs can handle short-lived objects much more efficiently.
In their HotSpot FAQ, Sun engineering states that pooling should definitely not be used any more,
that pooling actually gives worse performance with the latest HotSpot engines. This is rather a
sweeping statement. Object pools are still useful even with HotSpot, but presumably not as often
as previously. Certainly for shared resources, pooling will always be an option if the overhead
associated with creating a sharable resource is expensive. And for scaled applications, huge numbers of object creations and their associated garbage collections are still a very significant issue which can be completely bypassed using object pools.
Various recent tests have shown that the efficiency of pooling objects compared to creating and
disposing of objects is highly dependent on the size and complexity of the objects. And in some
applications where deterministic behavior is important, especially embedded applications, it is worth
noting that object pools have deterministic access and reclamation costs for both CPU and memory,
whereas object creation and garbage collection can be less deterministic (you cannot specify when garbage collection will occur, nor for how long it will last).
When recycling container objects, you need to dereference all the elements previously in the
container so that you don't prevent them from being garbage collected. Because there is this
extra overhead in recycling, it may not always be worth recycling containers. As usual for tuning, pooling is a technique best applied to ameliorate an object-creation bottleneck
that has already been identified, not one that should be applied up front. However to facilitate pooling being easily added to an application you should use the factory pattern to allocate the objects. This way you can change the allocation implementation at any time. Use a simple create ("new") with garbage collection reclamation initially for your factory method, then measure performance. If you identify a bottleneck caused by the object creation and garbage collection of a certain set of objects, you can easily change the underlying allocation implementation to use (thread local) pools.
The JavaPerformanceTuning.com team