@mrWan

Обычный метод копируется для каждого объекта или PHP оптимизирует и не делает копию методов для объектов?

class Foo {
    function method() {
         echo 'foo';
}
}
$a = new Foo;
$a->method();
$a = new Foo;
$a->method();

Это копии метода из класса или это один метод которому ссылаются объекты?
  • Вопрос задан
  • 110 просмотров
Пригласить эксперта
Ответы на вопрос 4
SerafimArts
@SerafimArts
Senior Notepad Reader
У каждой функции в PHP есть два контекста: Статический и объекта. Метод - это обычная именованная функция, у которой заранее объявлены оба этих контекста. Таким образом мы получаем, что метод один и выделение памяти под него тоже одно, но для разных объектов меняется контекст (т.е. ссылка на this), а значит создание нового объекта - это всего лишь выделение this контекста для метода, т.е. тупо один адрес.

Помимо этого, создавая новый объект память не выделяется вообще. Если объект идентичен предыдущему, то адрес нового объекта соответствует предыдущему с пометкой разделения ZVAL-структуры при мутациях (до некоторого времени даже баг был, когда функция spl_object_hash возвращала одну и ту же строчку для двух разных объектов, которые содержали одни и теже данные). Во время изменений объектов - ссылка на изменённое поле разделяется и новое значение пытается занять память тех переменных (напоминаю, что структура ZVAL едина для всех типов переменных), которые были помечены для уничтожения через GC (т.е. refcount=0), это позволяет избавиться от лишних аллокаций памяти. Такая модель поведения, например, позволяет делать клонирование (оператор clone) и инстанциирование (оператор new) объектов без выделений памяти вообще.

P.S. Так было в какой-то из 5.х веток, когда я исследовал поведение пыха. Сейчас же, когда на носу 7.3 - я уже хз, много поменяли, хотя в основном работа была проведена по уменьшению потребления памяти zval объектами, DCE оптимизациям и AVX/SSE инструкциям, так что не думаю что сильно.
Ответ написан
Комментировать
@vaajnur
битриксоид
конечно же один и тот же метод)) иначе будет пустая трата памяти
Ответ написан
@Yan-s
Кажется вы думаете совершенно не о том...
Можете описать контекст в котором возник такой вопрос?
Ответ написан
@alexalexes
Объекты - разные, метод - один и тот же.
Когда вы второй раз вызываете new для уже определенной переменной, выделяется память под новый объект, объект создается заново. Адрес памяти, куда ссылалась до этого $a зачищается сборщиком мусора по мере его возможностей.
PS: new буквально говорит "возьми ресурсы системы и построй мне объект по чертежу Foo!!!"
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы