スラブ割り当ては、オブジェクトの効率的なメモリ割り当てを目的としたメモリ管理メカニズムです。従来のメカニズムと比較して、割り当てと解放によって発生する断片化を軽減します。この手法は、特定の型のデータオブジェクトを含む割り当て済みメモリを保持し、同じ型のオブジェクトを後から割り当てる際に再利用するために使用されます。オブジェクトプールに似ていますが、メモリのみに適用され、他のリソースには適用されません。
スラブ割り当ては、ジェフ・ボンウィックによってSolaris 2.4カーネルで初めて導入されました。[ 1 ]ボンウィックは、「スラブ」という名前はケロッグのシリアルのCMの キャッチフレーズ「grab a slab」に由来すると主張しています。[ 2 ]
スラブ割り当ては、現在ではFreeBSD [ 3 ]やLinux [ 4 ]を含む多くのUnixおよびUnixライクなオペレーティングシステムで、SLABアロケータとその後継であるSLUB [ 5 ]の両方で広く使用されています。
スラブ割り当ては、カーネルデータオブジェクトの計算コストの高い初期化と破棄の頻度を大幅に削減し、メモリ割り当てのコストを上回る効果をもたらします。[ 1 ]カーネルがオブジェクトを頻繁に作成および削除する場合、初期化のオーバーヘッドコストによってパフォーマンスが大幅に低下する可能性があります。オブジェクトキャッシュにより、オブジェクトの状態を初期化する関数の呼び出し頻度が減少します。スラブ割り当てされたオブジェクトが使用後に解放されると、スラブ割り当てシステムは通常、それをキャッシュに保持し(破棄する作業を行うのではなく)、そのタイプのオブジェクトが次に必要になったときに再利用できるようにします(これにより、新しいオブジェクトの構築と初期化の作業が回避されます)。
スラブ割り当てでは、特定のタイプまたはサイズのデータ オブジェクトのキャッシュには、事前に割り当てられたメモリの「スラブ」が複数あります。各スラブ内には、オブジェクトに適した固定サイズのメモリ チャンクがあります。[ 6 ]スラブ アロケータはこれらのチャンクを追跡し、特定のタイプのデータ オブジェクトのメモリ割り当て要求を受け取ると、通常は既存のスラブから空きスロット (チャンク) を使用して要求を満たすことができます。アロケータがオブジェクトのメモリを解放するように要求されると、単にスロットを包含するスラブの空き (未使用) スロットのリストに追加します。同じタイプのオブジェクトを作成する (または同じサイズのメモリを割り当てる) 次回の呼び出しでは、そのメモリ スロット (または他の空きスロット) が返され、空きスロットのリストから削除されます。このプロセスにより、適切なメモリ スペースを検索する必要がなくなり、メモリの断片化が大幅に軽減されます。この文脈では、スラブとは、事前に割り当てられたメモリ チャンクを含むメモリ内の 1 つ以上の連続したページのことです。
スラブ割り当てアルゴリズムでは、以下の用語を定義します。
プログラムがキャッシュを設定する際、そのキャッシュに関連付けられたスラブに一定数のオブジェクトを割り当てます。この数は、関連付けられたスラブのサイズによって異なります。
スラブは、以下のいずれかの状態にある可能性があります。
システムは最初に、各スラブを「空」としてマークします。プロセスが新しいカーネルオブジェクトを要求すると、システムはそのオブジェクトのタイプのキャッシュ内の部分スラブ上で、そのオブジェクトの空き場所を探します。そのような場所が存在しない場合、システムは連続する仮想ページから新しいスラブを割り当て、それをキャッシュに割り当てます。新しいオブジェクトはこのスラブから割り当てられ、その場所は「部分」としてマークされます。
システムが事前にオブジェクトを構築し、スラブから容易に割り当てを行うため、割り当ては迅速に行われます。
スラブとは、マシンからキャッシュへのメモリ割り当ての1つを表し、そのサイズは通常、ページサイズの倍数です。スラブは複数のエントリに分割され、クライアントコードが新しいオブジェクト用のメモリを要求すると、キャッシュはこれらのエントリを要求します。そのため、スラブのどの部分が使用可能で、どの部分が既に占有されているかを追跡する必要があります。これは一般的に、「フリーリスト」と呼ばれる、新しいオブジェクトを格納する準備ができたスラブ内の空きエントリのリストを使用して行われます。
空きリストは、スラブのどのエントリが空いているかを示すインデックスの配列など、別のデータ構造である場合もあれば、スラブ内に埋め込まれている場合もある。Linux SLUBアロケータは、空きリストをポインタのリンクリストとして保持し、各ポインタは、それが表すスラブの空きメモリ領域に直接格納される。[ 7 ]
オペレーティングシステムは、格納するオブジェクトのサイズに応じて、異なるスラブサイズと内部レイアウトを使用する場合があります。大きなスラブが小さなスラブとは異なるレイアウトを持つ理由は、大きなスラブがページサイズの単位により効率的に詰め込まれるため、断片化が軽減されるからです。たとえば、特定のマシンのページサイズの少なくとも 1/8 のオブジェクトは、明示的なフリー リストを備えた「大きなスラブ」サイズから恩恵を受ける可能性がありますが、より小さなオブジェクトは、フリー リスト追跡を埋め込んだ「小さなスラブ」設定を使用する可能性があります。ボンウィックによるスラブ アロケータの最初のプレゼンテーションでは、すでに大きなスラブと小さなスラブのレイアウトを区別していました。[ 1 ]