2

Linux で shm_open を試していて、問題が発生しました。ftrunc を使用して共有メモリ セグメントのサイズを頻繁に変更し、mmap を使用してサイズ変更されたセグメントを再マップしています。ただし、20 メガバイト マークのあたりで、mmap から ENOMEM を取得します。

問題を解決するために私がやろうとしたこと:

まず、これらの sysctl パラメータについて知りました。私はそれらを再構成しました:

kernel.shmmax = 268435456
kernel.shmall = 2097152

(shmallはページ単位で指定)

この後も問題は発生しました。問題の原因となったサイズ変更の詳細を調査したところ、共有メモリ オブジェクトのサイズを変更するために行われた ftrunc の呼び出しが成功したことが明らかになりました (/dev/shm 内の対応するファイルは、要求された新しいサイズを持っていました)。

ここのドキュメントhttp://pubs.opengroup.org/onlinepubs/009695399/functions/mmap.htmlは、ENOMEM errnoの3つの考えられる原因を示唆しています:


[ENOMEM] MAP_FIXED が指定されましたが、範囲 [addr,addr+len) がプロセスのアドレス空間に許可されている範囲を超えています。または、MAP_FIXED が指定されておらず、マッピングを有効にするための十分なスペースがアドレス空間にない場合。

[ENOMEM] [ML] [Option Start] mlockall() で必要な場合、マッピングをメモリにロックできませんでした。これは、システムが提供できるよりも多くのスペースが必要になるためです。【オプション終了】

[ENOMEM] [TYM] [Option Start] fildes で指定された型付きメモリ オブジェクトに、len バイトを割り当てるのに十分な未割り当てのメモリ リソースが残っていません。【オプション終了】


MAP_FIXED またはロックを使用していません。/dev/shm のイメージのサイズは、3 番目の理由が問題ではないことを示唆しています。私の mmap 呼び出しは次のようになります。

mmap(メモリ、長さ、PROT_READ | PROT_WRITE、MAP_SHARED、fd、0)

ここで、mem は最初は 0 で、その後は最後に正常にマップされたアドレス mmap を参照します。

ulimit 設定がメモリ マップ可能なプロセスを 1 つのプロセスに制限している可能性があることを示唆する情報を見つけましたが、ここに問題があるとは思いません。念のため、私のマシンでは ulimit -a は次のようになります。

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 20
file size               (blocks, -f) unlimited
pending signals                 (-i) 16382
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65536
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

これが簡単なものであることを願っています:)

4

1 に答える 1

2

さて、私は先日自分の問題が何であるかを知りました。mmap のドキュメントを読み間違えました。これは、mmap が最初のパラメーター (私の場合は以前にマップされたアドレス) に基づいてマッピングを返し、結果は実装によって定義されると述べています。mmap が以前のマッピングを再マップするかもしれないという提案としてこれを受け取りましたが、これは確かにそうではありませんでした。これは、MAP_FIXED フラグを使用した場合にのみ発生する可能性がありますが、ドキュメントで推奨されているため、これを回避しました。いずれにせよ、新しいマッピングを作成する前に、munmap を使用して以前のマッピングを削除する必要がありました。この投稿が、私と同じ愚かな誤解をしている人の助けになることを願っています

于 2012-01-21T22:19:47.010 に答える