Ситуация такая: есть Linux-машина с 2 GB RAM. В какой-то момент
времени в работающей программе вызов sysconf(_SC_AVPHYS_PAGES)
возвращает количество страниц, общий размер которых составляет около
30 MB.
На основании этих данный делается попытка резервировать регион адресного пространства так:
mmap(NULL,
size,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS,
-1,
0)
где size == 262144 (256 килобайт).
Но этот вызов иногда проваливается! Очевидно (поправьте меня, если я
ошибаюсь), фрагментация памяти такова, что система не может выделить
последовательность страниц такой длины...
А вопрос такой: каким же образом можно понять, что в системе есть
достаточное количество свободной физической памяти, которую можно
резервировать (как?), не опасаясь ошибки?
Или это вообще невозможно? Может быть, есть какой-то приближённый
метод?
Заранее спасибо!
Заранее извиняюсь за наивный вопрос, но -- иногда бывает...
И какая политика overcommit (cat /proc/sys/vm/overcommit_memory)?
Не совсем понимаю, как в Линуксе может "провалиться" такой вызов.
MAP_NORESERVE должен, по идее, просто привести к segv при записи,
если памяти не хватает.
я тоже не понимаю в чем дело. но, конечно, дело не в
фрагментации физической памяти. разве что вы имели в
виду фрагментацию адресного пространства процесса.
хочу только сказать, что MAP_NORESERVE не будет принят во
внимание при strict overcommit (overcommit_memory == 2).
по вопросу о том, как узнать сколько "свободной" памяти.
в данном случае вы можете глянуть на mm/mmap.c:__vm_enough_memory()
и сделать то же самое, вся информация доступна через /proc.
но проще, мне кажется, просто сделать mmap() и проверить
код возврата.
> cat /proc/sys/vm/overcommit_memory
0
Нет, ограничений на ресурсы нет. Еслы вы имеете ввиду ulimit, то
> ulimit -a
core file size (blocks) 0
data seg size (kbytes) unlimited
file size (blocks) unlimited
max locked memory (kbytes) unlimited
max memory size (kbytes) unlimited
open files 1024
pipe size (512 bytes) 8
stack size (kbytes) unlimited
cpu time (seconds) unlimited
max user processes 8189
virtual memory (kbytes) unlimited
Но всё-таки, вот sysconf(_SC_AVPHYS_PAGES) говорит, что памяти -
завались, 30 мб. Как же воспользоваться этой информацией, и как
выделить получить в своё распоряжение некоторый регион страниц, не
опасаясь "провала" mmap?
> Но всё-таки, вот sysconf(_SC_AVPHYS_PAGES) говорит, что памяти -
> завались, 30 мб.
знать бы, что делает sysconf(_SC_AVPHYS_PAGES).
очень это смутное понятие, свободная память.
вы еще можете глянуть на sys_sysinfo(struct sysinfo*).
я думаю, sysconf() ее использует.
может, все-таки у вас действительно фрагментировано
адресное пространство? посмотрите /proc/self/maps.
потому что не найти 128K на 2Gb машине - это странно.
какое ядро? там, вроде бы было полно ошибок c
get_unmapped_area(), может в этом дело.
> > cat /proc/sys/vm/overcommit_memory
> 0
ну попробуйте 1 (OVERCOMMIT_ALWAYS).
Ядро - 2.4.19.
Гм, я смотрел, что делает sysconf(_SC_AVPHYS_PAGES). Это просто
значение free из /proc/meminfo, без прибавки cached и buffers...
OVERCOMMIT_ALWAYS попробую, спасибо.
> Гм, я смотрел, что делает sysconf(_SC_AVPHYS_PAGES). Это просто
> значение free из /proc/meminfo, без прибавки cached и buffers...
тогда это не более информативно, чем читать датчик случайных
чисел :)
но! если у вас даже во free болтается 30Mb, то ищите проблему
в самом процессе, который не получает 128K. разве что много
памяти commited другим процессам, OVERCOMMIT_ALWAYS должен
это решить.
что там meminfo про Committed_AS говорит?