Размер памяти занимаемый форком
Столкнулся со странным поведением при форке через pcntl_fork
Возьмем простой скрипт вечно живущего демона
pcntl_fork();
while (true) {
sleep(1);
}
И сравним потребление памяти у родителя и ребенка

Видно, что дочерний процесс занимет примерно на треть меньше операвтивной памяти.
Если копнуть немного глубже и сравнить вывод pmap -x 1172 1173 для обоих процессов увидим, такую картину

Если я правильно понимаю, то при старте php аллоцирует памяти с запасом на себя, а так же на все свои модули и этот запас довольно ощутимый, особенно если у вас на одном инстансе запускается множество демонов.
Получается таким хитрым способом можно урезать потребление памяти вашим демоном
if (pcntl_fork() > 0) {
die();
}
while (true) {
sleep(1);
}
В чем подвох, только в том, что придется тратить время на аллокацию памяти при необходимости?
Ответы (1 шт):
(обобщая комментарии выше)
При форке процесса используется copy-on-write страниц памяти между родителем и ребенком. Если php инициализируется 1 раз, а потом форкается, все форки разделяют (совместно используют) с родителем эту память. На этом можно экономить память и время на инициализацию (если она тюжелая).
Но тут надо учесть, что как только процесс-ребенок начнет активно работать с памятью, страницы памяти снова будут становиться раздельными. В какой мере память станет раздельной -- предсказать невозможно, только написать реальный код, запустить и сравнить.
/* О средсвах, позволяющих подробно узнать, какие страницы физической памяти используется совместно какими процессами из-за copy-on-write, мне не известно. */
Нашел достаточно простой способ:
pmap -X содержит столбик Pss -- "proportional set size" --
Объем страниц в памяти поделенный на количество процессов разделячщих страницы.
Так если у процесса 1000 страниц, которые пользует лично он, и еще 1000 страниц, общих с другим процессом, то Pss будет 1500.
https://www.kernel.org/doc/Documentation/filesystems/proc.txt
Запускаем скрипт, который инициализирует на куче большой массив, делает форк, и постепенно меняет случайные значения в массиве:
perl -e '$max=1000000; @c=1..$max; $pid=fork; @c[map{rand()*$max}1..100]=() while sleep 1'
Находим пару процессов скрипта и наблюдаем pmap -X:
perl -e 'while(sleep 1){$pids=join" ",map{/([0-9]+)/ && $1!=$$?"$1":()}`ps -ef|grep perl|grep sleep`; print `pmap -X $pids`}'
Видно, что Pss на строке heap стартует с половины Rss и постепенно увеличивается с убывающей скоростью.
Еще пишут, что /proc/<pid>/pagemap содержит соответствие между виртуальной и физической памятью (в бинарном виде), и имея CAP_SYS_ADMIN, можно его читать:
https://www.kernel.org/doc/Documentation/vm/pagemap.txt
Но с этим я эксперементировать уже не стал.