What is an object pool in C#?

An object pool in C# is a software design pattern that maintains a collection of reusable objects to optimize resource usage and improve performance. Instead of constantly creating and destroying expensive objects, the pool keeps pre-initialized objects ready for use.

The object pool pattern works on two fundamental operations −

  • Rent/Get: When an object is needed, it is retrieved from the pool.
  • Return: When the object is no longer needed, it is returned to the pool for reuse.

Object Pool Pattern Object Pool O O O Client Rent Return Available In Use

Using ObjectPool<T> in .NET

.NET Core and .NET 5+ provide a built-in ObjectPool<T> through the Microsoft.Extensions.ObjectPool package. This implementation is thread-safe and efficient for high-performance scenarios.

Example

using System;
using System.Text;
using Microsoft.Extensions.ObjectPool;

class Program {
   static void Main() {
      // Create a policy for StringBuilder objects
      var policy = new DefaultPooledObjectPolicy<StringBuilder>();
      
      // Create an object pool
      var pool = new DefaultObjectPool<StringBuilder>(policy);
      
      // Rent an object from the pool
      var sb = pool.Get();
      
      try {
         sb.Append("Hello, ");
         sb.Append("Object Pool!");
         Console.WriteLine("Result: " + sb.ToString());
      }
      finally {
         // Always return the object to the pool
         pool.Return(sb);
      }
      
      // Demonstrate reuse
      var sb2 = pool.Get();
      Console.WriteLine("Reused StringBuilder length: " + sb2.Length);
      pool.Return(sb2);
   }
}

The output of the above code is −

Result: Hello, Object Pool!
Reused StringBuilder length: 0

Custom Object Pool Implementation

Example

using System;
using System.Collections.Concurrent;

public class SimpleObjectPool<T> where T : class, new() {
   private readonly ConcurrentBag<T> _objects = new ConcurrentBag<T>();
   private readonly Func<T> _objectGenerator;
   
   public SimpleObjectPool() : this(() => new T()) { }
   
   public SimpleObjectPool(Func<T> objectGenerator) {
      _objectGenerator = objectGenerator ?? throw new ArgumentNullException(nameof(objectGenerator));
   }
   
   public T GetObject() {
      if (_objects.TryTake(out T item)) {
         return item;
      }
      return _objectGenerator();
   }
   
   public void PutObject(T item) {
      _objects.Add(item);
   }
}

// Example usage
class ExpensiveObject {
   public string Data { get; set; }
   public ExpensiveObject() {
      Console.WriteLine("Creating expensive object...");
   }
}

class Program {
   static void Main() {
      var pool = new SimpleObjectPool<ExpensiveObject>();
      
      // First usage - creates new object
      var obj1 = pool.GetObject();
      obj1.Data = "First use";
      Console.WriteLine("Using: " + obj1.Data);
      pool.PutObject(obj1);
      
      // Second usage - reuses existing object
      var obj2 = pool.GetObject();
      obj2.Data = "Second use";
      Console.WriteLine("Using: " + obj2.Data);
      pool.PutObject(obj2);
   }
}

The output of the above code is −

Creating expensive object...
Using: First use
Using: Second use

Common Use Cases

  • Database Connections: Pooling expensive database connection objects.
  • StringBuilder Objects: Reusing StringBuilder instances to avoid memory allocation.
  • HTTP Clients: Pooling HttpClient instances for web requests.
  • Graphics Objects: Reusing bitmap or graphics objects in games or image processing.
  • Buffer Arrays: Pooling byte arrays for I/O operations.

Benefits and Considerations

Benefits Considerations
Reduced object creation overhead Memory overhead of maintaining pool
Lower garbage collection pressure Thread-safety requirements
Predictable performance Object state cleanup needed
Resource conservation Pool size management

Conclusion

Object pools in C# are valuable for optimizing performance by reusing expensive objects instead of creating and destroying them repeatedly. Use object pools when dealing with costly object creation, high-frequency allocations, or when you need to reduce garbage collection pressure in performance-critical applications.

Updated on: 2026-03-17T07:04:35+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements