Стандартный способ создания новых процессов в Linux состоит в том, что объем памяти родительского процесса копируется, и он становится средой дочернего процесса до тех пор, пока не execv
будет вызван.
О каком объеме памяти мы говорим, виртуальном (о чем просил процесс) или резидентном (что на самом деле используется)?
Мотивация: у меня есть устройство с ограниченным пространством подкачки и приложение с большой разницей между виртуальной и резидентной памятью. Приложение не может быть разветвлено из-за нехватки памяти и хочет посмотреть, поможет ли попытка уменьшить размер виртуальной зоны.
источник
If enough is available the kernel will commit to the full virtual size of the parent for both processes after the fork.
Да спасибо. Это означает, что уменьшение виртуального следа процесса в среде с ограниченной памятью (ОЗУ и подкачка) может решить проблему невозможности форка.fork
сбой с сообщением об ошибке, указывающим на недостаток памяти. Тогда может помочь уменьшение использования виртуальной памяти процессом перед разветвлением.Не волнуйтесь, это делает ленивую копию (копирование при записи). Адреса виртуальной памяти обоих процессов изначально указывают на одни и те же страницы, но когда разветвленный процесс пытается изменить его, он фактически создает физическую копию страницы (с тех пор эта страница находится в двух местах в вашей ОЗУ).
Помните, что ни один из зарегистрированных следов памяти на самом деле не говорит вам, сколько оперативной памяти использует процесс. Из-за перестановки, совместного использования памяти и других проблем с виртуальной памятью невозможно знать наверняка. Некоторые части пространства памяти являются общими библиотеками (где их считать?), Некоторые ссылаются на не-RAM память (другие аппаратные устройства), некоторые в настоящее время выгружены, некоторые еще не скопированы (копирование при записи) и скоро. Прочитайте это:
https://lwn.net/Articles/642202/
источник
Есть настройки ядра
/ Proc / SYS / VM / overcommit_memory
Цитата из отличной статьи :
Это относится как к вилкам, так и к обычным malloc. Т.е. если вы установите его на 0, форк будет копироваться при записи. Копирование при записи означает, что после того, как приложение разветвится, обе его копии будут совместно использовать страницы памяти, если дочерний элемент или оригинал начнет изменять память.
В большинстве дистрибутивов я знаю, что overcommit равен 0. Но если вы установите его на 2, все страницы памяти будут полностью защищены реальной памятью, а в некоторых случаях под высоким давлением памяти будут более стабильными, но некоторые программы (я сталкивался с gitk), которые полагаются на сверхкоммитах не получится.
источник