Назад | Перейти на главную страницу

Общая память: сбой shmget: на устройстве не осталось места - как увеличить ограничения?

Я много раз вызываю shmget в своей программе, чтобы получить shm среднего размера 85840 байт. Я получаю около 32771 shm ok, затем shmget не возвращает сообщение shm, но выдает ошибку: «На устройстве не осталось места».

Я увеличил пределы ядра до:

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

Но все же проблема. Зачем?

Мне тоже нужно что-то помещать в /etc/security/limits.conf? У меня только "user - nofile 1000000", потому что программа также открывает примерно столько же файлов, сколько и shms.

Это результат бесплатного

$ 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 можно заменить, должно быть достаточно места.

Оказывается, shmmni в ядре ограничен 32768:

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

в файле ...version.../include/linux/ipc.h.

За исключением перекомпиляции ядра, это жесткое ограничение на количество сегментов разделяемой памяти.

Использовать ipcs -l для проверки фактически действующих ограничений, и ipcs -a и ipcs -m чтобы увидеть, что используется, чтобы вы могли сравнить результат. Посмотрите на nattch столбец: есть ли сегменты без подключенных процессов, которые не были удалены при выходе из процессов (что обычно означает сбой программы)? ipcrm может очистить их, хотя, если это тестовая машина, перезагрузка выполняется быстрее (и гарантирует, что ваши изменения в лимитах будут сохранены).

Параметры вашего ядра кажутся странными. В частности, shmall - это количество страниц, а не байтов, а 4 КБ - размер страницы по умолчанию (запустите getconf PAGESIZE чтобы проверить, что вы используете). Сколько у вас терабайт оперативной памяти?

Теперь вы говорите, что получаете около 32771 сегмента разделяемой памяти, что также составляет около 32768 (или от 2 до 15), что предполагает, что 16-битное int со знаком является ограничивающим фактором. И какое ядро ​​вы используете (так как у него будут свои ограничения)? Эти два могут быть связаны.

Так как shmget() выделяет новый сегмент разделяемой памяти, и вы, кажется, используете их много (учитывая ваш limits.conf), возможно ли, что вы используете слишком много сегментов разделяемой памяти? У меня нет большого опыта звонков shmget(), но мне кажется, что количество возможных открытых файлов (1000000) больше, чем количество разрешенных сегментов разделяемой памяти (SHMMNI), которое составляет 409600.