AspNetCore.Docs/aspnetcore/performance/ObjectPool.md

3.9 KiB

title author description monikerRange ms.author ms.date uid
Object reuse with ObjectPool in ASP.NET Core rick-anderson Tips for increasing performance in ASP.NET Core apps using ObjectPool. >= aspnetcore-1.1 riande 4/21/2023 performance/ObjectPool

Object reuse with ObjectPool in ASP.NET Core

By Günther Foidl, Steve Gordon, and Samson Amaugo

[!INCLUDE]

:::moniker range=">= aspnetcore-8.0"

xref:Microsoft.Extensions.ObjectPool is part of the ASP.NET Core infrastructure that supports keeping a group of objects in memory for reuse rather than allowing the objects to be garbage collected. All the static and instance methods in Microsoft.Extensions.ObjectPool are thread-safe.

Apps might want to use the object pool if the objects that are being managed are:

  • Expensive to allocate/initialize.
  • Represent a limited resource.
  • Used predictably and frequently.

For example, the ASP.NET Core framework uses the object pool in some places to reuse xref:System.Text.StringBuilder instances. StringBuilder allocates and manages its own buffers to hold character data. ASP.NET Core regularly uses StringBuilder to implement features, and reusing them provides a performance benefit.

Object pooling doesn't always improve performance:

  • Unless the initialization cost of an object is high, it's usually slower to get the object from the pool.
  • Objects managed by the pool aren't de-allocated until the pool is de-allocated.

Use object pooling only after collecting performance data using realistic scenarios for your app or library.

NOTE: The ObjectPool doesn't place a limit on the number of objects that it allocates, it places a limit on the number of objects it retains.

ObjectPool concepts

When xref:Microsoft.Extensions.ObjectPool.DefaultObjectPoolProvider is used and T implements IDisposable:

  • Items that are not returned to the pool will be disposed.
  • When the pool gets disposed by DI, all items in the pool are disposed.

NOTE: After the pool is disposed:

  • Calling Get throws an ObjectDisposedException.
  • Calling Return disposes the given item.

Important ObjectPool types and interfaces:

The ObjectPool can be used in an app in multiple ways:

  • Instantiating a pool.
  • Registering a pool in Dependency injection (DI) as an instance.
  • Registering the ObjectPoolProvider<> in DI and using it as a factory.

How to use ObjectPool

Call xref:Microsoft.Extensions.ObjectPool.ObjectPool`1.Get* to get an object and xref:Microsoft.Extensions.ObjectPool.ObjectPool`1.Return* to return the object. There's no requirement to return every object. If an object isn't returned, it will be garbage collected.

ObjectPool sample

The following code:

  • Adds ObjectPoolProvider to the Dependency injection (DI) container.
  • Implements the IResettable interface to automatically clear the contents of the buffer when returned to the object pool.

[!code-csharp]

NOTE: When the pooled type T doesn't implement IResettable, then a custom PooledObjectPolicy<T> can be used to reset the state of the objects before they are returned to the pool.

:::moniker-end

[!INCLUDE]

[!INCLUDE]