Каков масштаб проблемы циклических ссылок в PHP и стоит ли мне беспокоиться об этом? - PullRequest
5 голосов
/ 10 февраля 2009

Если я использую древовидную структуру узлов, подобную приведенному ниже коду, нужно ли беспокоиться о циклической ссылке?
Я читал, что PHP использует механизм выделения памяти, который может усложнить жизнь сборщику мусора при наличии циклических ссылок.

То, что я хочу знать, это:

  • Если мое дерево состоит только из нескольких узлов, скажем, 25, это проблема?
  • Будет ли освобождена память в конце скрипта или я медленно создаю проблему для сервера?
  • При каких обстоятельствах эта проблема повлияет на выполнение скрипта?
  • Разрешит ли уничтожение ссылок вручную проблему, и я всегда должен делать это?
class Node {
    private $parent;
    private $children;

    function addChild( Node $child ) {
        $this->children[] = $child;
        $child->setParent( $this );
    }

    function setParent( $parent ) {
        $this->parent = $parent;
    }
}

//eg
$node0 = new Node;
$node1 = new Node;

// nodes 1 and 2 have a circular reference to each other
$node0->addChild( $node1 );

Ответы [ 4 ]

4 голосов
/ 10 февраля 2009

Точка за точкой:

  • Если мое дерево состоит только из нескольких узлов, скажем, 25, это проблема?

Нет, если ваши узлы не настоящие монстры.

  • Будет ли освобождена память в конце скрипта или я медленно создаю проблему для сервера?

Когда переводчик выключается, вся память освобождается.

  • При каких обстоятельствах эта проблема повлияет на выполнение скрипта?

Я сомневаюсь, что вам будет о чем беспокоиться, если у вас нет очень низких пределов памяти или очень больших динамических структур данных. Если у вас есть 25 узлов, которые не создаются / освобождаются часто, у вас не возникнет проблем.

  • Разрешит ли уничтожение ссылок вручную проблему, и я всегда должен делать это?

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

3 голосов
/ 10 февраля 2009

Может быть и так, но, поскольку он выбрасывает все объекты в конце каждого запроса (если вы не кэшируете), я не думаю, что многие программисты PHP беспокоятся об этом.

Если вы пишете сценарии командной строки на PHP, то, возможно, у вас есть повод для беспокойства по этому поводу, но вам придется написать какой-то довольно запутанный код PHP, прежде чем он станет чем-то, о чем стоит беспокоиться. И если это так, у вас есть большие проблемы.

Удачи.

2 голосов
/ 10 февраля 2009

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

Разработайте сейчас, примите меры предосторожности для явного разыменования в методе __destruct () и обновите до 5.3, когда это возможно.

2 голосов
/ 10 февраля 2009

Учитывая характер большинства страниц PHP - то есть процесс выполняется для веб-страницы и отбрасывается по завершении - я, скорее, сомневаюсь, что это проблема. Я не видел проблем с циклическими ссылками и использовал их без проблем. По моему опыту, вы столкнетесь с большим количеством проблем с простым потреблением памяти, но PHP 5 несколько смягчил это, отказавшись от простого копирования объектов и массивов, если не указано иное.

...