In computer programming, an object pool is a construct of objects which can be used concurrently. Typically, a client object which requires resources which are managed by the object pool will request an object from the pool and perform operations on the returned object. Object pooling offers a significant performance boost and is most efficient in situations where the cost of initializing a class instance is high and the amount of instantiations of a particular class is also frequent.
If no objects are available in the pool, a new object is created and returned to the pool when it is no longer referenced (it's no longer being used). This allows for control of resources and limits the amount of work necessary to instantiate and initialize new objects. The object pool will release objects within the pool when requests for objects diminishes.
This contruct is typically employed in software in situations where instantiating an object is prohibitively expensive, or the object itself uses a significant amount of resources and must be controlled in a fixed pool size.
When writing an object pool, the programmer has to be careful to make sure the state of the objects returned to the pool is reset back to a useable state for the next use of the object. Often if this is not observed, the object will be in some state that was unexpected by the client program and that will cause the client program to fail.
The presence of stale state is not always an issue; it becomes dangerous when the presence of stale state causes the object to behave differently. For example, an object that represents authentication details may break if the "successfully authenticated" flag is not reset before it is passed out, since it will indicate that a user is correctly authenticated (possibly as someone else) when they haven't yet attempted to authenticate. However, it will work just fine if you fail to reset the identity of the last authentication server used, since this is not important in normal operation, but is used for debugging.
Often, the afflicted software will yield unpredictable and sporadic results when performing operations that seem routine. This problem arises when a used object returned from the pool to a client is in a state that is incompatible with that expected by the client. The problem is also more apparent in object pools which contain class instances that are very complex as opposed to simpler classes with few properties and/or methods.
An object pool is a useful construct for managing limited resources and reducing the amount of initialization necessary when a class is used very frequently. However, clients which receive a used object must receive an object which is in an initialized state. That is, they should presume that the object is ready to be used after the constructor runs or the object is returned from a class factory which manages the pool. The pool must take care to ensure that objects are cleaned up to an initialized state in the time between returning to the pool and being passed out to a client.
The original class programmer may not have written cleanup code, relying on construction to set a sensible state; in C++, there may also be an assumption that resources are released in the destructor. This leads to two problems: the object cleanup code is not executed before the pool manager returns an instance to the client, so the client receives an object instance which has unpredictable state, and the object may hang on to resources it will not need again while resting in the pool.
For example, consider a programmer who writes a CreditCardPool class which returns CreditCardProcessor objects. A client program needs to authorize a credit card, and it does so by retrieving a CreditCardProcessor from the pool. However, the program gets a CreditCardProcessor object which was used by another program and was released without clearing its state and contains information about another account.
As the program runs on this "dirty" instance, the card authorization declines. However, when the ApprovalCode field is checked, it has a value that shows the card was approved, but this was an approval code for someone else's account on a previous use of the object... not the current instance the client program thinks it is. Depending on the client code, this may cause phantom approvals (we have a valid ApprovalCode, so the card must have processed OK), or production of a message like "Card declined, cause: card approved". In the worst case, the client may leak sensitive information back to the user (for example, the details of the successfully approved card, instead of the card that's been declined).
The typical fix for this situation is to mandate a "clean" method on each interface type the object pool supports. Objects are then cleared of state just prior to returning instances to clients, or just after they are passed back into the pool. For more complex objects, two methods may be required; one to clean up state and free resources when the object is returned to the pool, and one to prepare the object just before it is passed out of the pool to a client.