Pergunta

Se eu estou usando uma estrutura de árvore de nós semelhante ao código abaixo, eu tenho que se preocupar com a referência circular?
Eu li que o PHP usa um mecanismo de alocação de memória que pode tornar a vida muito difícil para o coletor de lixo quando há referências circulares envolvidos.

O que eu quero saber é:

  • Se a minha árvore consiste de apenas alguns nós, dizem 25, isso é um problema?
  • Será que a memória ser liberada no final do script ou estou lentamente criando um problema para o servidor?
  • Em que circunstâncias se este problema tem um efeito durante a execução do script?
  • Será manualmente destruindo as referências resolver o problema e que eu deveria sempre fazê-lo?
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 );
Foi útil?

Solução

ponto por ponto:

  • Se a minha árvore consiste de apenas alguns nós, dizem 25, isso é um problema?

A não ser que os nós são verdadeiros monstros.

  • Será que a memória ser liberada no final do script ou estou lentamente criando um problema para o servidor?

Quando os fecha intérprete para baixo toda a memória é liberada.

  • Em que circunstâncias se este problema tem um efeito durante a execução do script?

Eu duvido que você vai ter nada para se preocupar, a menos que você tem limites de memória muito baixos ou estruturas de dados dinâmica muito grandes. Se você tem 25 nós que não estão sendo criados / libertados frequentemente você não terá um problema.

  • Será manualmente destruindo as referências resolver o problema e que eu deveria sempre fazê-lo?

Ele vai ajudar. Ao carregar um grande conjunto de dados em nosso banco de dados com Propel que funcionou em um monte de problema com o consumo de memória que nós monitorados para referências circulares não sendo libertados. Nossa solução foi chamar um método que cancelou todas as referências.

Outras dicas

Talvez sim, mas uma vez que joga fora todos os objetos no final de cada pedido (a menos que você está caching), eu não acho que muitos programadores PHP preocupar com isso.

Se você estiver escrevendo scripts de linha de comando em PHP, então talvez você tem um caso para se preocupar com isso, mas você tem que ser a escrever algum código PHP muito complicada antes que se torne algo digno de se preocupar com. E se esse for o caso, você tem problemas maiores.

Boa sorte.

Dada a natureza da maioria das páginas de PHP - isto é, o processo é executado para uma página web e é jogado fora na conclusão - eu duvido que este é um problema. Eu não vi problemas com referências circulares antes e tê-los usado sem problemas. Na minha experiência, você vai correr em mais problemas com mero consumo de memória, mas PHP 5 mitigou que pouco deslocando longe de objetos apenas copiadoras e matrizes a menos que dito de outra forma.

PHP 5,3 incluirão características de detecção de referência e destruição circulares. É uma configuração opcional, e só deve ser usado quando necessário porque o coletor de lixo terá um impacto no desempenho, mas é feito sob medida para o seu exemplo.

Desenvolver agora, tomar as precauções para explicitamente excluir a referência em um método __destruct (), e atualizar para 5,3 quando possível.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top