#php #memory-management
#php #управление памятью
Вопрос:
Сегодня на работе у меня возник спор с коллажем о передаче больших данных между областями. Миф заключался в том, что ссылка использует меньше памяти / процессора при переходе между двумя областями. Мы создаем доказательство концепции, кто был прав … итак:
function by_return($dummy=null) {
$dummy = str_repeat("1",100 * 1024 * 1024);
return $dummy;
}
function by_reference(amp;$dummy) {
$dummy = null;
$dummy = str_repeat("1",100 * 1024 * 1024);
}
echo memory_get_usage()."/".memory_get_peak_usage()."n";
//1 always returns: 105493696/105496656
$nagid = by_return();
echo memory_get_usage()."/".memory_get_peak_usage()."n";
unset($nagid);
//2 always returns: 105493696/210354184 even if we comment 1st part
by_reference($dummy);
echo memory_get_usage()."/".memory_get_peak_usage()."n";
unset($dummy);
Но кажется, что по ссылке он потребляет больше памяти в соответствии с функцией «memory_get_peak_usage()»
Как вы видите, использование больших данных для возврата намного разумнее, чем использование в качестве ссылки, но вопрос в том, почему? Приветствуется любое разъяснение 🙂
Ответ №1:
Это связано с тем, как php обрабатывает переменные, и немного противоречит интуиции для любого, кто работал в C или C .
Передача по ссылке, чтобы быть умнее PHP, не рекомендуется. PHP фактически не создает копии данных, если в этом нет необходимости (т. Е. вы изменяете значение переменной, когда на нее имеется более 1 ссылки), стратегия оптимизации, очень похожая на копирование при записи для страниц общей памяти.
Итак, допустим, у вас есть переменная, значение которой вы передаете несколько раз в данном скрипте. Если вы затем берете эту переменную и передаете ее по ссылке, вы фактически дублируете переменную, а не просто получаете указатель на объект.
Это потому, что внутри PHP zvals (структура данных, которую PHP использует для хранения переменных) могут быть только ссылочными переменными или без ссылки переменными. Таким образом, не имеет значения, что такое поле ref_count в zval, потому что это не ссылочная переменная (поле is_ref структуры zval). Таким образом, внутренне PHP вынужден создать новый zval и присвоить его полю is_ref значение true, тем самым удваивая объем памяти.
Скажите своему коллеге, чтобы он прекратил попытки перехитрить PHP. Передача по ссылке, если она не выполнена на 100% идеально во всем коде, вызовет большие накладные расходы и удвоит использование памяти.
Для более подробного обсуждения, пожалуйста, смотрите эту ссылку: http://porteightyeight.com/2008/03/18/the-truth-about-php-variables /
Комментарии:
1. Ссылка кажется мертвой: (Я предполагаю, что это зеркальный сайт: porteightyeight.wordpress.com/2008/03/18 /…