次の方法で共有


Kestrel のメモリ管理

トム・ダイクストラ

この記事では、メモリ プールからの自動削除やメモリ プール メトリックの使用など、 Kestrel内のメモリを管理するためのガイダンスを提供します。

メモリ プールからの自動削除

Kestrel、IIS、および HTTP.sys によって使用されるメモリ プールは、アプリケーションがアイドル状態または負荷が低い場合に、メモリ ブロックを自動的に削除します。 この機能は自動的に実行され、手動で有効または構成する必要はありません。

この自動削除機能は、全体的なメモリ使用量を削減し、さまざまなワークロードでアプリケーションの応答性を維持するのに役立ちます。 10 より前のバージョンの .NET では、プールによって割り当てられたメモリは、使用中でない場合でも予約されたままでした。

メモリプールの指標を使用する

ASP.NET Core サーバーの実装で使用される既定のメモリ プールには、メモリ使用量パターンの監視と分析に使用できるメトリックが含まれています。 メトリックは、 "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に注意してください。