Microsoft.NET

……………………………………………….Expertise in .NET Technologies

Object Pooling in Microsoft .NET

Posted by Ravi Varma Thumati on January 5, 2010

Introduction

Object Pooling is nothing new. It is a concept that implies that we can store a pool of objects in memory to be reused later and, hence, reduce the load of object creation to a great extent. An Object Pool, also known as a Resource Pool, is a list/set of ready to be used reusable objects that reduce the overhead of creating each object from the scratch whenever a request for an object creation comes in. This is somewhat similar to the functioning of a Connection Pool, but with some distinct differences. This article throws light on this concept (Object Pooling) and discusses how we can implement a simple generic Object Pool in .NET.

What is an Object Pool?

An Object Pool may be defined as a container of objects that are ready for use. Lists of ready-to-be-used objects are contained in this pool. Whenever a new request for an object creation comes in, the request is served by allocating an object from the pool. Therefore, it reduces the overhead of creating and re-creating objects each time an object creation is required. “An object pool is an object that holds a list of other objects, ready to make them available for use (to yet another object, probably). It does the management work involved, like keeping track of which objects are currently in use, how many objects the pool holds, whether this number should be increased.”

Why is an Object Pool required?

The biggest advantage of using Object Pooling is that it minimizes the consumption of memory and the system’s resources by recycling and re-using objects as and when it is needed and serving the request for new objects from the pool of ready-to-be-used objects. The objects that the application is done with (the objects are no longer needed) are sent back to the pool rather than destroying them from the memory. According to MSDN, “Once an application is up and running, memory utilization is affected by the number and size of objects the system requires. Object pooling reduces the number of allocations, and therefore the number of garbage collections, required by an application. Pooling is quite simple: an object is reused instead of allowing it to be reclaimed by the garbage collector. Objects are stored in some type of list or array called the pool, and handed out to the client on request. This is especially useful when an instance of an object is repeatedly used, or if the object has an expensive initialization aspect to its construction such that it’s better to reuse an existing instance than to dispose of an existing one and to create a completely new one from scratch.”

How does an Object Pool work?

When an object is requested, it is served from the pool. When the object is disposed, it is placed back into the pool to await the next request that might come in at a later point in time. The pool initially consists of a number of objects. When a request for creation of an object comes in, the request is server from the pool of objects and the number of the available objects in the pool decreases by one. This process continues until the pool runs out of objects. The pool remains in memory as long as there is at least one object in the pool. The pool facilitates reusability and eliminates the overhead involved in creation of objects whenever they are requested. The following section discusses how an Object Pool (though somewhat similar to a Connection Pool) differs from a Connection Pool.

How does Object Pooling and Connection Pooling differ?

There are distinct differences between Object pooling and Connection Pooling. Object Pooling is great in the sense that it can optimize access to expensive resources (like file handles or network connections) by pooling them in memory and reusing them as and when they are needed. According to MSDN, “Object pooling lets you control the number of connections you use, as opposed to connection pooling, where you control the maximum number reached.”

Implementing an Object Pool in C#

We would design an object pool based on some predefined goals/objectives. These are stated as under the following.

  • Ease of use and reusable
  • Thread Safe
  • Type Safe
  • >Scalable
  • Configurable

These are the basic objectives that the pool should adhere to. With these in mind, we will now implement a simple Object Pool in C# and use this pool for creation, usage and destruction of objects.

The Pool Manager Class

The following code example illustrates how an object pool can be created. I have provided enough comments to enable the reader to understand how the Pool Manager class works. This class is based on the Singleton Pattern, i.e., there can be at any point of time only one instance of this class.

Listing 1

1 using System;

2 using System.ComponentModel;

3 using System.Collections;

4 using System.Threading;

5

6 namespace ObjectPooling

7 {

8     /// <summary>

9     /// A class to manage objects in a pool.

10

11     ///The class is sealed to prevent further inheritence

12     /// and is based on the Singleton Design.

13     /// </summary>

14     public sealed class PoolManager

15     {

16         private Queue poolQueue = new Queue();

17         private Hashtable objPool = new Hashtable();

18         private static readonly object objLock = new object();

19         private const int POOL_SIZE = 10;

20         private int objCount = 0;

21         private static PoolManager poolInstance = null;

22

23         /// <summary>

24         /// Private constructor to prevent instantiation

25         /// </summary>

26         private PoolManager()

27         {

28

29         }

30

31         /// <summary>

32         /// Static constructor that gets

33         ///called only once during the application’s lifetime.

34

35         /// </summary>

36         static PoolManager()

37         {

38             poolInstance = new PoolManager();

39         }

40

41         /// <summary>

42         /// Static property to retrieve the instance of the Pool Manager

43

44         /// </summary>

45

46         public static PoolManager Instance

47         {

48             get

49             {

50                 if(poolInstance != null)

51                 {

52                     return poolInstance;

53                 }

54

55                 return null;

56             }

57         }

58

59         /// <summary>

60

61         /// Creates objects and adds them in the pool

62         /// </summary>

63         /// <param>The object type</param>

64         public void CreateObjects(object obj)

65         {

66             object _obj = obj;

67             objCount = 0;

68             poolQueue.Clear();

69             objPool.Clear();

70

71             for (int objCtr = 0; objCtr < POOL_SIZE ; objCtr ++)

72             {

73                 _obj = new object();

74

75                 lock(objLock)

76                 {

77                     objPool.Add(_obj.GetHashCode(),_obj);

78                     poolQueue.Enqueue(_obj);

79                     objCount ++;

80                 }

81             }

82         }

83

84         /// &lt;summary&gt;

85

86         /// Adds an object to the pool

87         /// &lt;/summary&gt;

88         /// &lt;param&gt;Object to be added&lt;/param&gt;

89         /// &lt;returns&gt;True if success, false otherwise&lt;/returns&gt;

90

91         public bool AddObject(object obj)

92         {

93             if(objCount == POOL_SIZE)

94                 return false;

95

96             lock(objLock)

97             {

98                 objPool.Add(obj.GetHashCode(),obj);

99                 poolQueue.Enqueue(obj);

100                 objCount ++;

101             }

102

103             return true;

104         }

105

106         /// &lt;summary&gt;

107

108         /// Releases an object from the pool at the end of the queue

109         /// &lt;/summary&gt;

110         /// &lt;returns&gt;The object if success, null otherwise&lt;/returns&gt;

111

112         public object ReleaseObject()

113         {

114             if(objCount == 0)

115                 return null;

116

117             lock(objLock)

118             {

119                 objPool.Remove(poolQueue.Dequeue().GetHashCode());

120                 objCount –;

121                 if (poolQueue.Count > 0)

122                     return poolQueue.Dequeue();

123             }

124

125             return null;

126         }

127

128         /// &lt;summary&gt;

129

130         /// Releases an object from the pool

131         /// &lt;/summary&gt;

132         /// &lt;param&gt;Object to remove from the pool&lt;/param&gt;

133         /// &lt;returns&gt;The object if success, null otherwise&lt;/returns&gt;

134

135         public object ReleaseObject(object obj)

136         {

137             if(objCount == 0)

138                 return null;

139

140             lock(objLock)

141             {

142                 objPool.Remove(obj.GetHashCode());

143                 objCount –;

144                 RePopulate();

145                 return obj;

146             }

147         }

148

149         /// &lt;summary&gt;

150

151         /// Method that repopulates the

152         ///Queue after an object has been removed from the pool.

153         /// This is done to make the queue

154         ///objects in sync with the objects in the hash table.

155         /// &lt;/summary&gt;

156         private void RePopulate()

157         {

158             if(poolQueue.Count &gt; 0)

159                 poolQueue.Clear();

160

161             foreach (int key in objPool.Keys)

162             {

163                 poolQueue.Enqueue(objPool[key]);

164             }

165         }

166

167         /// &lt;summary&gt;

168

169         /// Property that represents the current no of objects in the pool

170         /// &lt;/summary&gt;

171         public int CurrentObjectsInPool

172         {

173             get

174             {

175                 return objCount;

176             }

177         }

178

179         /// &lt;summary&gt;

180

181         /// Property that represents the maximum no of objects in the pool

182         /// &lt;/summary&gt;

183         public int MaxObjectsInPool

184         {

185             get

186             {

187                 return POOL_SIZE;

188             }

189         }

190     }

191 }

Using the Pool Manager Class

The following code snippets in Listings 2, 3 and 4 show how we can use the PoolManager created in Listing 1.

Listing 2

object obj1 = new object();

object obj2 = new object();

PoolManager poolManager = PoolManager.Instance;

poolManager.AddObject(obj1);

poolManager.AddObject(obj2);

MessageBox.Show(poolManager.CurrentObjectsInPool.ToString());

poolManager.ReleaseObject(obj1);

MessageBox.Show(poolManager.CurrentObjectsInPool.ToString());

object obj = null;

for(;;)

{

obj = poolManager.ReleaseObject();

if(obj != null)

MessageBox.Show(obj.GetHashCode().ToString());

else

{

MessageBox.Show(“No more objects in the pool”);

break;

}

}

Listing 3

object obj1 = new object();

object obj2 = new object();

PoolManager poolManager = PoolManager.Instance;

poolManager.AddObject(obj1);

poolManager.AddObject(obj2);

MessageBox.Show(poolManager.CurrentObjectsInPool.ToString());

poolManager.ReleaseObject(obj1);

MessageBox.Show(poolManager.CurrentObjectsInPool.ToString());

object obj = null;

for(;;)

{

obj = poolManager.ReleaseObject();

if(obj != null)

MessageBox.Show(obj.GetHashCode().ToString());

else

{

MessageBox.Show(“No more objects in the pool”);

break;

}

}

Listing 4

PoolManager poolManager = PoolManager.Instance;

ArrayList arr = new ArrayList();

poolManager.CreateObjects(arr);

object obj = poolManager.ReleaseObject();

MessageBox.Show(“No of objects in Pool is: ” +

poolManager.CurrentObjectsInPool.ToString(),

“The hash code of the released object is: ” +

obj.GetHashCode().ToString());

obj = poolManager.ReleaseObject();

MessageBox.Show(“No of objects in Pool is: ” +

poolManager.CurrentObjectsInPool.ToString(),

“The hash code of the released object is: ” +

obj.GetHashCode().ToString());

Note how we have used the PoolManager in the code listings above. The CreateObjects method has been used in Listing 4 to create a specified number of objects of the ArrayList type and store them in the pool. However, the major drawback of this design is that there would be enough boxing and un-boxing overhead involved on storing and retrieving the objects to and fro from the pool. To eliminate this, I would recommend the usage of Generics. Further, the size of the pool (the maximum number of objects that the pool can contain) is also fixed and is not configurable. I leave it to the readers to make the necessary changes to the Pool Manager class to suit their needs.

Conclusion

Object Pooling is a mechanism that facilitates re-using of the existing objects in a pool (a container of live objects) rather than creating or re-creating them a new each time they are needed. This article has discussed the basic concepts of Object Pooling and how we can implement the same in .NET using C# as the language of choice.

Advertisements

One Response to “Object Pooling in Microsoft .NET”

  1. Very effectively written information. It will likely be worthwhile to anyone who usess it, together with myself. Sustain the good work – for sure i will try more posts.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: