Solaris モジューラデバッガ

アロケータの基礎

カーネルメモリーアロケータの仕事は、仮想記憶領域を他のカーネルサブシステムに区分けすることです。これらのカーネルサブシステムは、通常、クライアントと呼ばれます。この節では、アロケータの操作の基礎を説明し、また、このマニュアルで後で使用するいくつかの用語を説明します。

バッファの状態

カーネルメモリーアロケータが作用する領域は、カーネルヒープを構成する仮想記憶のバッファの集まりです。これらのバッファは、キャッシュと呼ばれる一様なサイズと目的を持ったセットにグループ化されます。各キャッシュには、バッファのセットが含まれています。これらのバッファの一部は現在未使用です。つまり、これらはまだアロケータのクライアントに割り当てられていません。残りのバッファは割り当て済みです。つまり、そのバッファへのポインタが、アロケータのクライアントに提供されています。アロケータのクライアントが、割り当てられているバッファへのポインタを保持していない場合には、そのバッファは解放することができないので、リークしていると言われます。リークしているバッファは、カーネル資源を無駄使いしている正しくないコードを示しています。

トランザクション

kmem トランザクションとは、バッファの割り当て済み状態と未使用状態の間の移行のことです。アロケータは、各トランザクションの一部として、バッファの状態が有効であることを確認することができます。さらに、アロケータには、事後分析のためにトランザクションを記録しておく機能があります。

スリーピング割り当てと非スリーピング割り当て

標準 C ライブラリの malloc(3C) 関数とは異なり、カーネルメモリーアロケータは、ブロックする (またはスリープする) ことができ、クライアントの要求を満たすのに十分な仮想記憶が使用可能になるまで待機することができます。これは、kmem_alloc(9F) の「flag」パラメタによって制御されます。KM_SLEEP フラグが設定されている kmem_alloc(9F) への呼び出しは、決して失敗することはありません。この呼び出しは、資源が使用可能になるまでいつまでも待機します。

カーネルメモリーキャッシュ

カーネルメモリーアロケータは、管理しているメモリーをキャッシュのセットに分割します。すべての割り当てはこれらのキャッシュから供給され、これらのキャッシュは kmem_cache_t データ構造体によって表されます。各キャッシュは固定のバッファサイズを持っており、これはそのキャッシュが満たす最大割り当てサイズを表します。各キャッシュは、管理するデータのタイプを示す文字列による名前を持っています。

一部のカーネルメモリーキャッシュは特殊な目的用で、特定の種類のデータ構造体だけを割り当てるために初期化されます。この一例を挙げると、"thread_cache" があります。これは、kthread_t タイプの構造体だけを割り当てます。このキャッシュのメモリーは、kmem_cache_alloc() 関数によってクライアントに割り当てられ、kmem_cache_free() 関数によって解放されます。


注 -

kmem_cache_alloc()kmem_cache_free() は公開 DDI インタフェースではありません。これらは Solaris の将来のリリースでは変更または削除される場合があるので、これらに依存したコードを作成しないでください。


"kmem_alloc_" で始まる名前を持つキャッシュは、カーネルの汎用メモリー割り当てスキーマを実装します。これらのキャッシュは、kmem_alloc(9F)kmem_zalloc(9F) のクライアントにメモリーを提供します。これらの各キャッシュは、そのサイズが、そのキャッシュのバッファサイズと次に小さいキャッシュのバッファサイズの間にあるという要求を満たします。たとえば、このカーネルは kmem_alloc_8kmem_alloc_16 キャッシュを持っています。この場合、kmem_alloc_16 キャッシュは、9 〜 16 バイトのメモリーを要求するすべてのクライアント要求を処理します。クライアント要求のサイズに関係なく、kmem_alloc_16 キャッシュの各バッファのサイズは 16 バイトです。14 バイト要求の場合、要求は kmem_alloc_16 キャッシュによって満たされるので、バッファの残りの 2 バイトは使用されません。

キャッシュの最後のセットは、カーネルメモリーアロケータ自体が記述するために内部的に使用するキャッシュです。これには、名前が "kmem_magazine_" または "kmem_va_" で始まるキャッシュ、kmem_slab_cachekmem_bufctl_cache などがあります。