内存管理 Kestrel

汤姆·迪克斯特拉

本文提供有关管理内存的指南,包括从内存 Kestrel池自动逐出和使用内存池指标。

从内存池自动移除

当应用程序空闲或负载不足时,IIS 和 HTTP.sys 使用的 Kestrel内存池会自动逐出内存块。 该功能会自动运行,无需手动启用或配置。

这种自动逐出功能可减少总体内存使用率,并帮助应用程序在不同工作负荷下保持响应。 在低于 10 的 .NET 版本中,即使未使用,池分配的内存仍保留。

使用内存池指标

ASP.NET 核心服务器实现使用的默认内存池包括指标,可用于监视和分析内存使用模式。 指标位于名称 "Microsoft.AspNetCore.MemoryPool"下。

有关指标及其用法的信息,请参阅 ASP.NET 核心指标

管理内存池

除了通过逐出不需要的内存块来有效使用内存池之外,ASP.NET Core 还提供内置的 IMemoryPoolFactory 接口及其默认实现,这些接口可通过依赖项注入获得。

下面的代码示例演示了一个简单的后台服务,该服务使用内置的内存池工厂实现来创建内存池。 这些池受益于自动逐出功能:

public class MyBackgroundService : BackgroundService
{
    private readonly MemoryPool<byte> _memoryPool;

    public MyBackgroundService(IMemoryPoolFactory<byte> factory)
    {
        _memoryPool = factory.Create();
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                await Task.Delay(20, stoppingToken);
                // do work that needs memory
                // consider checking _memoryPool.MaxBufferSize
                var rented = _memoryPool.Rent(100);
                rented.Dispose();
            }
            catch (OperationCanceledException)
            {
                return;
            }
        }
    }
}

若要使用自定义内存池工厂,请创建一个实现 IMemoryPoolFactory 并将其注册到依赖项注入的类,如以下示例所示。 以这种方式创建的内存池也受益于自动逐出功能:

services.AddSingleton<IMemoryPoolFactory<byte>,
CustomMemoryPoolFactory>();

public class CustomMemoryPoolFactory : IMemoryPoolFactory<byte>
{
    public MemoryPool<byte> Create()
    {
        // Return a custom MemoryPool implementation
        // or the default, as is shown here.
        return MemoryPool<byte>.Shared;
    }
}

使用内存池时,请注意池的 MaxBufferSize