By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,304 Members | 3,172 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,304 IT Pros & Developers. It's quick & easy.

Is it ok to create a Simple memory pool using singleton and a queue of pointers?

P: 2
I have been looking at memory pools and was wondering what would be wrong with creating a singleton which create a "pool" of (allocated) pointers to a given struct/class( in the case below Messages ), and then when a client needs a "new" one pass them one from your free message queue. Any thoughts, potential problems, etc, would be appreciated. Thanks.

Expand|Select|Wrap|Line Numbers
  1. class MsgPool
  2. {
  3. public:
  4.  
  5.     ~MsgPool();
  6.  
  7.     static void recycleMem(Message* msg);
  8.     static Message* newMessage();
  9.     static MsgPool* createInstance();
  10.  
  11. private:
  12.  
  13.     MsgPool();
  14.  
  15.     static MsgPool* msgPoolInstance;
  16.     static Message* msgPtr;
  17.     static std::queue<Message*> msgPtrPool;
  18. };
  19.  
  20. MsgPool* MsgPool::msgPoolInstance = NULL;
  21. std::queue<Message*> MsgPool::msgPtrPool;
  22. Message* MsgPool::msgPtr;
  23.  
  24. //CCONSTRUCTOR/DESTRUCTORS
  25. //----------------------------------------------------------------------------------------------//
  26.  
  27. MsgPool::MsgPool()
  28. {
  29.     while (msgPtrPool.size() < INITPTRPOOL) {
  30.         msgPtr = new Message();
  31.         msgPtrPool.push(msgPtr);
  32.     }
  33. }
  34. MsgPool::~MsgPool()
  35. {
  36.     if (msgPoolInstance != NULL) {
  37.         while (!msgPtrPool.empty()) {
  38.             msgPtr = msgPtrPool.front();
  39.             msgPtrPool.pop();
  40.             delete msgPtr;
  41.         }
  42.  
  43.         delete msgPoolInstance;
  44.         msgPoolInstance = NULL;
  45.     }
  46. }
  47. //----------------------------------------------------------------------------------------------//
  48.  
  49. //INSTANCE CREATION
  50. //----------------------------------------------------------------------------------------------//
  51. //This function creates the one and only instance of the message pool
  52. MsgPool* MsgPool::createInstance()
  53. {
  54.     if (msgPoolInstance == NULL) {
  55.         msgPoolInstance = new MsgPool();
  56.     }
  57.         return msgPoolInstance;
  58. }
  59. //----------------------------------------------------------------------------------------------//
  60.  
  61. //"ALLOCATION/DEALLOCATION"
  62. //----------------------------------------------------------------------------------------------//
  63.  
  64. //This function puts a given pointer back into the pool
  65. void MsgPool::recycleMem(Message* msg)
  66. {
  67.     if (msg != NULL) {
  68.         msgPtrPool.push(msg);
  69.     }
  70.     else
  71.         std::cerr <<"Passed NULL ptr" << std::endl;
  72. }
  73.  
  74. //This function returns a message pointer
  75. Message* MsgPool::newMessage()
  76. {
  77.     //If out of memory in pool allocate new memory
  78.     if (msgPtrPool.empty()) {
  79.         return (new Message);
  80.     }
  81.     else
  82.     {
  83.         msgPtr = msgPtrPool.front();
  84.         msgPtrPool.pop();
  85.         return msgPtr;
  86.     }
  87.  
  88. }
Jan 31 '11 #1
Share this Question
Share on Google+
3 Replies


Oralloy
Expert 100+
P: 983
Of course it's ok to create such a pool.

In some instances, it's sometimes beneficial to application performance, too.

The question is rather - is it appropriate or necessary to create this memory pool to solve your higher level problem.

Also, you might search around for memory pool template classes that you might use. If you multiple pools to implement, it is best if they all behave similarly. You'll have a lot more confidence in your application.

Cheers!
Oralloy
Jan 31 '11 #2

P: 2
Assuming we are strictly seeking performance, would the implementation used above work as well(better?) as overloading new and delete and creating a "real" memory pool?
Feb 1 '11 #3

Oralloy
Expert 100+
P: 983
Peter,

What new and [icode]delete[/icode[ will get you, of course, is dynamic C++ objects on top of your memory pool, which might be very valuable for an application that needs to do rapid recovery of pooled objects. (e.g. deleting all objects from a pool is simply accomplished by declaring the pool closed - no destructors get called or anything - a technique used in embedded systems).

Your design, as it stands, does one "important" thing - it prevents the need for continuous construction and destruction of Message objects. Since I don't know how expensive that operation is, I can't comment further.

You might get a bit more optimization by using a self-managed stack of available Message objects, rather than a std::queue<> object.

Also, have you considered what your code should do, when your pool runs out of objects? Or is this a case which cannot happen? [Object use being controlled by the enclosing application, which is beyond the pool's control].

Since you're optimizing time, you get a bit of an improvement by not calling the Message c'tor and d'tor. You will get a bit more by using a self-managed stack of messages without. Is that enough?

May I ask what your real problem is?

The reason I'm asking, is because replacing the C++ memory management mechanism is an expensive optimization that generally results in low gain. Which is not to say that there aren't times when it is appropriate. I would estimate a week or of man time to write, debug, and "prove" that your code is truly working as required. Not only do you have to write your optimized memory pool (which is mostly done), but you probably should write error detection into the Message class, which detects when the pool is not used (for the maintennece guys that come after you).

Luck!
Feb 1 '11 #4

Post your reply

Sign in to post your reply or Sign up for a free account.