Поделиться через


Управление памятью в Kestrel

Том Дайкстра

В этой статье приведены рекомендации по управлению памятью, Kestrelвключая автоматическое вытеснение из пулов памяти и использование метрик пула памяти.

Автоматическое удаление из пула памяти

Пулы памяти, используемые службами KestrelIIS и HTTP.sys автоматически вытесняют блоки памяти, когда приложение неактивно или находится под низкой нагрузкой. Функция выполняется автоматически и не должна быть включена или настроена вручную.

Эта функция автоматического вытеснения снижает общее использование памяти и помогает приложениям реагировать на различные рабочие нагрузки. В версиях .NET до 10 память, выделенная пулом, остается зарезервированной, даже если она не используется.

Использование метрик пула памяти

Пул памяти по умолчанию, используемый реализацией сервера ASP.NET Core, включает метрики, которые можно использовать для мониторинга и анализа шаблонов использования памяти. Метрики находятся под именем "Microsoft.AspNetCore.MemoryPool".

Сведения о метриках и их использовании см. в ASP.NET Core метрики.

Управление пулами памяти

Помимо эффективного использования пулов памяти путем вытеснения ненужных блоков памяти, 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.