Чтобы ответить на ваш вопрос, я немного расскажу о распределении памяти PHP, а затем о вашем конкретном вопросе.
О выделении памяти PHP
При написании PHPРасширения, есть два вида выделения памяти, которые вы можете выполнить:
- отслеживаемые выделения памяти
- постоянные выделения памяти
Отслеживаемое выделение памяти является оптимизациейэто позволяет движку PHP иметь больше контроля над необработанным выделением памяти.Менеджер памяти Zend (ZendMM) действует как оболочка над стандартными библиотеками выделения памяти.Этот диспетчер памяти позволяет PHP избежать утечек памяти путем очистки любой отслеживаемой памяти, которая не была явно освобождена в конце запроса.Кроме того, это позволяет двигателю устанавливать пределы памяти (такие как php.ini
memory_limit
).По этим причинам отслеживаемая память также упоминается как память на запрос .
Постоянное выделение памяти - это стандартное выделение памяти, управляемое библиотекой C (например, malloc
и друзья).Стоит также отметить, что в C ++ new
и delete
обычно вызывают до malloc
и free
соответственно.В PHP постоянное выделение памяти сохраняется после обработки запроса и может существовать для обслуживания более одного запроса.По этой причине возможна утечка памяти с этими типами распределения.
В PHP API есть некоторые макросы, которые определены для выполнения отслеженных или постоянных выделений памяти.Например, emalloc
и efree
являются аналогами malloc
и free
для управления отслеживаемой (т.е. по запросу) памятью.Макросы pemalloc
и pefree
предназначены для отслеживаемых или постоянных распределений, имеющих параметр для переключения.Например, pemalloc(32,1)
выделяет блок из 32 постоянных байтов, тогда как pemalloc(32,0)
эквивалентен emalloc(32)
, который выделяет блок из 32 отслеживаемых байтов.
В дополнение к необработанным функциям выделения памяти, PHP APIтакже обеспечивает управление распределением памяти, инициируемым функциями более высокого уровня.Например, создание структуры PHP7 zend_string
с zend_string_init
позволяет вам выбрать, какой тип выделения памяти вы хотите через третий параметр.Это соответствует общепринятому идиому в API: 0
обозначает отслеживаемое выделение и 1
обозначает постоянное выделение.
Относительно zend_string
, zend_string_init
и RETURN_STR
Я не так знаком с PHP7, как с PHP5, но многие концепции перенесли, и я думаю, что прочитал достаточно исходного кода, чтобы ответить на вопрос.Когда вы присваиваете zend_string
для zval
, используя RETURN_STR
, zval
становится ответственным за освобождение zend_string
(в PHP5 это было просто char*
, но концепция та же самая).Движок Zend ожидает, что большинство, если не все объекты будут размещены с помощью отслеживаемого менеджера памяти.В PHP5 строка, присвоенная zval
, должна быть выделена через emalloc
, поскольку код всегда вызывает efree
в строковом буфере, когда zval
уничтожается.В PHP7, кажется, исключение , поскольку структура zend_string
может запомнить, какой тип размещения использовался.Несмотря на это, рекомендуется всегда использовать отслеживаемые выделения по умолчанию, если только у вас нет веских причин поступить иначе.Поэтому ваш текущий код выглядит хорошо, поскольку он передает 0
в качестве третьего параметра zend_string_init
.
Уничтожение zend_string
не должно быть явным в вашем коде, так как zval
будет обрабатывать это внемного позже.Кроме того, этот процесс зависит от того, как пользовательское пространство работает с возвращаемым zval
.Вам не о чем беспокоиться.