Click here to Skip to main content
15,886,788 members
Articles / Programming Languages / C++
Article

Object Pooling for Generic C++ classes

Rate me:
Please Sign up or sign in to vote.
3.29/5 (19 votes)
4 May 2003CPOL2 min read 78.4K   2.3K   31   12
Implements a basic object pooling scheme for generic C++ objects.

Introduction

The default memory allocator is not efficient when it comes to frequent new and delete operations. There are a number of general purpose allocators that replace the standard one. There are certain situations when you want to improve performance at the cost of using more memory. This is especially true for small objects that are frequently created and destroyed in processing intensive applications. So, I decided to create a class that pools instances of classes, so that new and delete works on an array of already existing objects.

Usage

To enable pooling for a class, you publically inherit from this class, as shown below:

class myclasstobepooled : public ObjectPool< myclasstobepooled >

Call this function before any objects are created:

myclasstobepooled::initialize();

Call this function after all objects are deleted:

myclasstobepooled::finalize();

Implementation

The ObjectPool class maintains a static vector of the pointers of the template type. The overridden new and delete operators manage the list.

There is an option to enable or disable thread safety. This is provided so that the critical section calls can be excluded, if the class is used in a single threaded environment, or if the new and delete operations are always performed from the same thread.

You can disable multithreading support by commenting the line:

#define ___USE_MT___

The constructor and destructor gets called even when the placement new and delete is used. So, there is no special code required to call the constructor and destructor.

Additional information

Initially I was thinking about allocating the memory using malloc and calling the constructor and destructor manually. But, this would be along the lines of a general purpose memory allocator, where the global new and delete are overridden.

Suppose you have a class myclass.

// allocate
myclass* p = malloc(sizeof(myclass));     

// call the constructor, does not allocate any memory
new (p) myclass(); 


// call the destructor manually
p->~myclass();

Conclusion

If you have a class that you new and delete frequently in a performance critical part of the code, you can get substantial benefits by using this class.

Downloads

A non-STL version version of the class is available in the downloads section. This was provided by Christian Kaiser.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
GeneralNice Pin
peterchen3-Aug-10 0:12
peterchen3-Aug-10 0:12 
QuestionDeriving classes from pooled class Pin
lhost26-May-10 21:44
professionallhost26-May-10 21:44 
GeneralBoost Pool Library Pin
Stephen Hewitt11-Nov-07 13:29
Stephen Hewitt11-Nov-07 13:29 
GeneralNon STL version, some problems... Pin
Armel Asselin4-May-04 21:59
Armel Asselin4-May-04 21:59 
GeneralTiming tests Pin
c2j230-Apr-03 2:47
c2j230-Apr-03 2:47 
GeneralRe: Timing tests Pin
User 988530-Apr-03 2:58
User 988530-Apr-03 2:58 
GeneralRe: Timing tests Pin
c2j230-Apr-03 3:30
c2j230-Apr-03 3:30 
GeneralRe: Timing tests Pin
User 988530-Apr-03 3:34
User 988530-Apr-03 3:34 
GeneralIt's a good idea. Pin
workingpad21-Apr-03 15:50
workingpad21-Apr-03 15:50 
QuestionAdditional Overhead? Pin
Mike McCann21-Apr-03 12:33
Mike McCann21-Apr-03 12:33 
AnswerRe: Additional Overhead? Pin
User 988521-Apr-03 12:52
User 988521-Apr-03 12:52 
Using sizeof is spot on to findout the memory footprint of a class. Why are you bothered very much about the additional 4 bytes of memory? Is this a very specific need that you have?

Answer to a)
The base class (ObjectPool) has a virtual destructor that causes the vtable array pointer to be added to all the objects, which explains the 4 bytes (the size of a 32 bit address).

It is not advisable to make the destructor non-virtual. At this point, it is of not much importance because there is no run-time cleanup. But, a complete implementation of this scheme would require that if the number of objects in use decrease, the size of the pool be reduced using some algorithm. It may require that the delete operator have some code to delete the objects. Since the delete call will be from the base class, it is essential that you have a virtual destructor.

IMO, the 4 byte overhead is not much.

Answer to b)
You can avoid it by adding the new and delete overloading directly into your class.

Thomas


My article on a reference-counted smart pointer that supports polymorphic objects and raw pointers


modified 29-Aug-18 21:01pm.

GeneralRe: Additional Overhead? Pin
Jens Nilsson6-May-03 7:11
Jens Nilsson6-May-03 7:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.