Partilhar via


Gestão de memória em Kestrel

Por Tom Dykstra

Este artigo fornece orientações para gerir memória em Kestrel, incluindo a expulsão automática de pools de memória e a utilização de métricas de pool de memória.

Expulsão automática do pool de memória

Os pools de memória usados pelo Kestrel, IIS e HTTP.sys removem automaticamente os blocos de memória quando o aplicativo está ocioso ou sob baixa carga. O recurso é executado automaticamente e não precisa ser ativado ou configurado manualmente.

Esse recurso de remoção automática reduz o uso geral de memória e ajuda os aplicativos a permanecerem responsivos sob cargas de trabalho variáveis. Nas versões do .NET anteriores à 10, a memória alocada pelo pool permanecia reservada mesmo quando não estava em uso.

Usar métricas do pool de memória

O pool de memória padrão usado pelas implementações do servidor ASP.NET Core inclui métricas, que podem ser usadas para monitorar e analisar padrões de uso de memória. As métricas estão sob o nome "Microsoft.AspNetCore.MemoryPool".

Para obter informações sobre métricas e como usá-las, consulte ASP.NET métricas principais.

Gerenciar pools de memória

Além de utilizar pools de memória de forma eficiente, eliminando blocos de memória desnecessários, ASP.NET Core fornece uma interface IMemoryPoolFactory incorporada e a sua implementação padrão, que estão disponíveis através de injeção de dependências.

O exemplo de código a seguir mostra um serviço em segundo plano simples que usa a implementação de fábrica do pool de memória interno para criar pools de memória. Estas piscinas beneficiam da funcionalidade de despejo automático:

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;
            }
        }
    }
}

Para usar uma fábrica de pool de memória personalizada, crie uma classe que implemente IMemoryPoolFactory e registre-a com injeção de dependência, como faz o exemplo a seguir. Os pools de memória criados dessa forma também se beneficiam do recurso de remoção automática:

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;
    }
}

Quando você estiver usando um pool de memória, esteja ciente do pool MaxBufferSize.