名前
madvise - メモリ利用に関するアドバイスを与える
書式
#include <sys/mman.h>
int madvise(void *start, size_t length, int advice);
説明
madvise() システムコールは、アドレス start からはじまる length バイトのメモリブロックのページング入出力をどう扱えば良いか、 カーネルにアドバイスする。 これを用いると、 アプリケーションからカーネルに、 マップされたメモリや共有メモリをどのように扱ってほしいか伝えることができ、 カーネルはそれに応じて先読みやキャッシュなどの適切な手法を選択できる。 このコールはアプリケーションの動作そのものには影響しない (MADV_DONTNEED の場合は別) が、 性能には影響しうる。 なおこのアドバイスを受け入れるかどうかはカーネルに任される。
アドバイスはパラメータ advice によって与える。以下のいずれかを指定できる。
MADV_NORMAL | |
特別な扱いは行わない。これがデフォルトである。 | |
MADV_RANDOM | |
ページ参照はランダムな順序で行われそうだ。 (したがって、先読みはあまり効果がなさそうだ。) | |
MADV_SEQUENTIAL | |
ページ参照はシーケンシャルな順序で行われそうだ。 (したがって与えた範囲のページは積極的に先読みしておくと良いだろう。 またアクセスが終わったら速やかに解放して良い。) | |
MADV_WILLNEED | |
近い将来にアクセスされそうだ。 (したがってこれらのページを今のうちに先読みしておくといいだろう。) | |
MADV_DONTNEED | |
しばらくアクセスはなさそうだ。 (現時点でアプリケーションは与えた範囲の処理を終えている。 したがってカーネルはこれに関連するリソースを解放して良い。) これ以降この範囲のページへのアクセスがあると、 成功はするが、メモリの内容をマップ元のファイルからロードし直すことになる (mmap(2) を見よ) か、 または元ファイルがないマップページでは アクセスがあったときに 0 埋めが行われることになる。 | |
MADV_REMOVE (Linux 2.6.16 以降) | |
指定された範囲のページと関連するバッキングストアを解放する。 現在のところ、 shmfs/tmpfs だけがこれに対応している。 他のファイルシステムでは -ENOSYS が返される。 | |
MADV_DONTFORK (Linux 2.6.16 以降) | |
fork(2) が行われた後、指定された範囲のページを子プロセスが利用できないようにする。 この機能は、書き込み時コピー (copy-on-write) 方式で、 fork(2) の後で親プロセスがページに書き込みを行った場合に ページの物理位置が変化しないようにするのに有効である (ページの再配置はハードウェアがそのページに DMA 転送を行うような場合に 問題を起こすことがある)。 | |
MADV_DOFORK (Linux 2.6.16 以降) | |
MADV_DONTFORK の影響を取り消し、デフォルトの動作に戻す。 つまり、 fork(2) の前後でマッピングは継承されるようになる。 | |
返り値
madvise() は成功すると 0 を返す。 エラーが起こると -1 を返し、 errno を適切な値に設定する。
エラー
EAGAIN | 何らかのカーネルリソースが一時的に利用できなかった。 |
EBADF | 指定したマップは存在するが、ファイルではないところをマップしている。 |
EINVAL | len の値が負、 start がページ境界でない、 advice が正しい値でない、 アプリケーションがロックされたページや共有ページを (MADV_DONTNEED で) 解放しようとしている、など。 |
EIO | (MADV_WILLNEED の場合) この範囲のページングを行うと、 プロセスの RSS (resident set size) の最大値を越えてしまう。 |
ENOMEM | (MADV_WILLNEED の場合) メモリが足りず、ページングに失敗した。 |
ENOMEM | 指定した範囲のアドレスが、現在マップされていない。 あるいはプロセスのアドレス空間の内部にない。 |
準拠
POSIX.1b. POSIX.1-2001 では、 posix_madvise(3) を POSIX_MADV_NORMAL などの定数とともに記述していた (それぞれの振る舞いはここで述べたものに近い)。 ファイルアクセスに対しても posix_fadvise(3) という類似の関数が存在する。
MADV_REMOVE, MADV_DONTFORK, MADV_DOFORK は Linux 固有である。
注意
Linux での注意
現在の Linux の実装 (2.4.0) では、 このシステムコールをアドバイスというよりは命令と見ている。 したがってこのアドバイスに対して通常行われる動作が不可能な場合は、 エラーを返すことがある (上記の エラー の記述を見よ)。 この振舞いは標準とは異なる。
Linux の実装では start のアドレスはページ境界の値でなければならない。また length は 0 であっても構わない。 また Linux 版の madvise() では、指定されたアドレス範囲にマップされていない部分があると、 これらを無視して残りの部分にアドバイスを適用する (しかしシステムコールに対してはちゃんと ENOMEM を返す)。
関連項目
getrlimit(2), mincore(2), mmap(2), mprotect(2), msync(2), munmap(2)