уничтожение объекта со ссылками на сам

При отладке фрагмента кода, который истощал память, я обнаружил очень интересную проблему, и, самое главное, я не знаю, как ее исправить.

Приложение состоит примерно из одного объекта Survey , который содержит несколько объектов Question . Объекты вопросов содержат ссылку на опрос, в котором они находятся, это необходимо, чтобы иметь возможность получать ответы, например, на другие вопросы.


Следующий цикл вызывал переполнение памяти:

foreach ( $survey_ids_arr as $survey_id ) {
    $Survey = new Survey( $survey_id );
}

Ничего особенного не происходит в конструктор обзора;

  • получение его свойств из базы данных
  • получение свойств всех вопросов из базы данных
  • создание объекта Question для каждого вопроса (передача ссылки на $ this)
  • добавление всех объектов Question во внутренний массив

и глядя на код, можно сказать, что на каждой итерации объект очищается из памяти, поскольку переменная $ Survey перезаписывается. Правильно ?? Неправильно :)

Память накапливается по мере прохождения сценария цикла - добавление вызовов memory_get_usage () показывает, что память, используемая объектом Survey, не освобождается должным образом, в данный момент другой объект присвоен переменной $ Survey . Даже вызов unset ($ Survey) в конце цикла не освобождает память.


Виновником являются ссылки на $ this , которые передаются объектам вопросов при творчество. Эти ссылки предотвращают удаление объекта из памяти - как указано в руководстве по php.net:

Метод деструктора будет вызван, как только будут удалены все ссылки на конкретный объект.

Итак, что мешает объекту быть очищено, есть ссылки на себя. Красиво, да? :)

Итак, проблема в том, что мой объект - убийца памяти. К сожалению, я не могу придумать решения (кроме как написать уродливый метод, который очищает вопросы и вызывает его из цикла). Деструктор в Survey не вариант; как указано выше, это не называется , потому что объекты Вопроса все еще имеют ссылки.

Есть идеи? Кто-то, должно быть, уже столкнулся с этой проблемой - родительские-содержащие-дочерние-объекты - это не редкость, не так ли?

6
задан Rijk 18 August 2011 в 12:15
поделиться