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
これが簡単なものであることを願っています:)