Object pool pattern: Difference between revisions

Content deleted Content added
Pearle (talk | contribs)
m Changing {{cleanup-date}} to {{cleanup-date|December 2005}}
Clean up
Line 1:
{{wikify}}
{{cleanup-date|December 2005}}
 
In [[computer programming]], an '''object pool''' is a constructset of objectsinitialised which[[Object can(computer bescience)|objects]] usedthat concurrently.are kept ready to Typicallyuse, arather clientthan objectallocated whichand requiresdestroyed resourceson whichdemand. are managedA byclient theof objectthe pool will request an object from the pool and perform operations on the returned object. When Objectthe poolingclient offershas afinished significantwith performancean boostobject, andit isreturns mostit efficient in situations whereto the costpool, ofrather initializingthan adestroying classit. instanceIt is higha andspecific the amounttype of instantiations[[factory of a particular class is also frequentobject]].
 
Object pooling can offer a significant performance boost; it is most effective in situations where the cost of initializing a class instance is high, the rate of instantiation of a class is high, and the number of instantiations in use at any one time are low.
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.
 
== Handling of empty pools ==
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.
 
Object pools employ one of three strategies to handle a request when there are no spare objects in the pool.
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.
 
# Fail to provide an object (and return an error to the client)
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.
# Allocate a new object, thus increasing the size of the pool. Pools that do this usually allow to you see the [[high water mark]] (the maximum number of objects ever used).
# In a multithreaded environment, a pool may block the client until another thread returns an object to the pool.
 
== Pitfalls ==
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.
 
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 useablesensible 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. Usually, the pool is responsible for resetting the objects, not the clients. Object pools full of objects with dangerously stale state are sometimes called object [[cesspools]]
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 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.
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).
 
Inadequate resetting of objects may also provide an information leak. If an object contains confidential data (e.g. a user's credit card numbers) that isn't cleared before the object is passed to a new client, a malicious or buggy client may disclose the data to an unauthorized party.
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.
 
[[Category:Optimizations]]