web-dev-qa-db-ja.com

共有メモリ:shmgetが失敗する:デバイスにスペースが残っていません-制限を増やす方法は?

プログラムで何度もshmgetを呼び出して、平均サイズ85840バイトのshmを取得します。私は約32771 shmを取得しましたが、shmgetはshmを返しませんが、「デバイスにスペースが残っていません」というエラーが返されます。

カーネルの制限を次のように増やしました。

$ sysctl -A|grep shm
kernel.shmmax = 33554432
kernel.shmall = 1677721600
kernel.shmmni = 409600

しかし、まだ問題が発生します。どうして?

/etc/security/limits.confにも何かを入れる必要がありますか?プログラムはshmsとほぼ同じ数のファイルも開くため、「user-nofile 1000000」しかありません。

これは無料の出力です

$ free
          total       used       free     shared    buffers     cached
Mem:       8150236    7261676     888560          0     488100    3270792
-/+ buffers/cache:    3502784    4647452 
Swap:     12287992     554692   11733300

そしてipcs

$ ipcs -lm                                                                         

------ Shared Memory Limits --------
max number of segments = 409600
max seg size (kbytes) = 1638400
max total shared memory (kbytes) = 6710886400
min seg size (bytes) = 1

Shmはスワップアウトできると思いますので、十分なスペースがあるはずです。

2
j13r

カーネルではshmmniは32768に制限されています。

#define IPCMNI 32768  /* <= MAX_INT limit for ipc arrays (including sysctl changes) */

ファイル...version.../include/linux/ipc.h

カーネルの再コンパイルが不足しているため、これは共有メモリセグメントの数のハード制限です。

3
ramruma

使用する ipcs -l実際に有効な制限を確認し、ipcs -aおよびipcs -mを使用して何が使用されているかを確認し、出力を比較できるようにします。 nattch列を見てください。プロセスが終了したときに削除されなかった、プロセスがアタッチされていないセグメントはありますか(通常、プログラムがクラッシュしたことを意味します)? ipcrmはそれらをクリアできますが、これがテストマシンである場合は、再起動が速くなります(制限への変更が確実に反映されるようになります)。

カーネルパラメータがおかしいようです。特に、shmallはバイト数ではなくページ数であり、4kBがデフォルトのページサイズです(実行getconf PAGESIZEを使用して、使用しているものを確認します)。 RAM)は何テラバイトありますか?

ここで、約32771の共有メモリセグメントを取得するとします。これは、約32768(または2から15)でもあり、符号付き16ビット整数が制限要因であることを示唆しています。そして、どのカーネルを実行していますか(これには独自の制限があるため)? 2つは関連している可能性があります。

2
ramruma

shmget()が新しい共有メモリセグメントを割り当て、それらの多くを使用しているように(limits.confを考慮して)、共有メモリセグメントを使用しすぎている可能性はありませんか? shmget()の呼び出しの経験はあまりありませんが、開いている可能性のあるファイルの数(1000000)が、許可されている共有メモリセグメント(SHMMNI)の数である409600よりも多いようです。

0
wzzrd