При отладке фрагмента кода, который истощал память, я обнаружил очень интересную проблему, и, самое главное, я не знаю, как ее исправить.
Приложение состоит примерно из одного объекта Survey
, который содержит несколько объектов Question
. Объекты вопросов содержат ссылку на опрос, в котором они находятся, это необходимо, чтобы иметь возможность получать ответы, например, на другие вопросы.
Следующий цикл вызывал переполнение памяти:
foreach ( $survey_ids_arr as $survey_id ) {
$Survey = new Survey( $survey_id );
}
Ничего особенного не происходит в конструктор обзора;
и глядя на код, можно сказать, что на каждой итерации объект очищается из памяти, поскольку переменная $ Survey перезаписывается. Правильно ?? Неправильно :)
Память накапливается по мере прохождения сценария цикла - добавление вызовов memory_get_usage ()
показывает, что память, используемая объектом Survey, не освобождается должным образом, в данный момент другой объект присвоен переменной $ Survey
. Даже вызов unset ($ Survey)
в конце цикла не освобождает память.
Виновником являются ссылки на $ this
, которые передаются объектам вопросов при творчество. Эти ссылки предотвращают удаление объекта из памяти - как указано в руководстве по php.net:
Метод деструктора будет вызван, как только будут удалены все ссылки на конкретный объект.
Итак, что мешает объекту быть очищено, есть ссылки на себя. Красиво, да? :)
Итак, проблема в том, что мой объект - убийца памяти. К сожалению, я не могу придумать решения (кроме как написать уродливый метод, который очищает вопросы и вызывает его из цикла). Деструктор в Survey не вариант; как указано выше, это не называется , потому что объекты Вопроса все еще имеют ссылки.
Есть идеи? Кто-то, должно быть, уже столкнулся с этой проблемой - родительские-содержащие-дочерние-объекты - это не редкость, не так ли?