|
| 1 | +## Automatic eviction from memory poools |
| 2 | + |
| 3 | +The memory pools used by Kestrel, IIS, and HTTP.sys automatically evict memory blocks when the application is idle or under less load. The feature runs automatically and doesn't need to be enabled or configured manually. |
| 4 | + |
| 5 | +In versions of .NET earlier than 10 earlier than 10, memory allocated by the pool would remain reserved, even when not in use. This feature releases memory back to the system when the app is idle for a period of time. This eviction reduces overall memory usage and helps applications stay responsive under varying workloads. |
| 6 | + |
| 7 | +### Use memory pool metrics |
| 8 | + |
| 9 | +The default memory pool used by the ASP.NET Core server implementations includes metrics, which can be used to monitor and analyze memory usage patterns. The metrics are under the name `"Microsoft.AspNetCore.MemoryPool"`. |
| 10 | + |
| 11 | +For information about metrics and how to use them, see <xref:log-mon/metrics/metrics>. |
| 12 | + |
| 13 | +## Manage memory pools |
| 14 | + |
| 15 | +Besides using memory pools efficiently by evicting unneeded memory blocks, ASP.NET Core improves the experience of creating memory pools. It does this by providing a built-in [IMemoryPoolFactory](https://source.dot.net/#Microsoft.AspNetCore.Connections.Abstractions/IMemoryPoolFactory.cs) and a `MemoryPoolFactory` implementation. It makes the implementation available to your application through dependency injection. |
| 16 | + |
| 17 | +The following code example shows a simple background service that uses the built-in memory pool factory implementation to create memory pools. These pools benefit from the automatic eviction feature: |
| 18 | + |
| 19 | +```csharp |
| 20 | +public class MyBackgroundService : BackgroundService |
| 21 | +{ |
| 22 | + private readonly MemoryPool<byte> _memoryPool; |
| 23 | + |
| 24 | + public MyBackgroundService(IMemoryPoolFactory<byte> factory) |
| 25 | + { |
| 26 | + _memoryPool = factory.Create(); |
| 27 | + } |
| 28 | + |
| 29 | + protected override async Task ExecuteAsync(CancellationToken stoppingToken) |
| 30 | + { |
| 31 | + while (!stoppingToken.IsCancellationRequested) |
| 32 | + { |
| 33 | + try |
| 34 | + { |
| 35 | + await Task.Delay(20, stoppingToken); |
| 36 | + // do work that needs memory |
| 37 | + var rented = _memoryPool.Rent(100); |
| 38 | + rented.Dispose(); |
| 39 | + } |
| 40 | + catch (OperationCanceledException) |
| 41 | + { |
| 42 | + return; |
| 43 | + } |
| 44 | + } |
| 45 | + } |
| 46 | +} |
| 47 | +``` |
| 48 | + |
| 49 | +To use your own memory pool factory, make a class that implements `IMemoryPoolFactory` and register it with dependency injection, as the following example does. Memory pools created this way also benefit from the automatic eviction feature: |
| 50 | + |
| 51 | +```csharp |
| 52 | +services.AddSingleton<IMemoryPoolFactory<byte>, |
| 53 | +CustomMemoryPoolFactory>(); |
| 54 | + |
| 55 | +public class CustomMemoryPoolFactory : IMemoryPoolFactory<byte> |
| 56 | +{ |
| 57 | + public MemoryPool<byte> Create() |
| 58 | + { |
| 59 | + // Return a custom MemoryPool implementation |
| 60 | + // or the default, as is shown here. |
| 61 | + return MemoryPool<byte>.Shared; |
| 62 | + } |
| 63 | +} |
| 64 | +``` |
0 commit comments