2009-02-09 10 views
5

Jeśli używam struktury drzewa węzłów podobnej do poniższego kodu, czy muszę się martwić o odwołanie cykliczne?
Przeczytałem, że PHP używa mechanizmu alokacji pamięci, który może uczynić życie bardzo trudnym dla odśmiecacza, gdy są zaangażowane odwołania kołowe.Jaka jest skala okrężnego odniesienia PHP i czy powinienem się tym przejmować?

Co chcę wiedzieć:

  • Jeśli moje drzewo składa się z zaledwie kilku węzłach, powiedzmy 25, jest to problem?
  • Czy pamięć zostanie zwolniona na końcu skryptu, czy powoli tworzę problem dla serwera?
  • W jakich okolicznościach problem ten wystąpi podczas wykonywania skryptu?
  • Czy ręczne zniszczenie odnośników rozwiąże problem i czy zawsze powinienem to zrobić?
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); 
+0

Myślę, że powinno być dobrze. AFAIK, tak działa implementacja DOM PHP. –

Odpowiedz

4

punkt po punkcie:

  • Jeśli moje drzewo składa się z zaledwie kilku węzłach, powiedzmy 25, jest to problem?

Nie, chyba że Twoje węzły to prawdziwe potwory.

  • Czy pamięć zwolniona na końcu skryptu albo ja powoli tworząc problem dla serwera?

Po zamknięciu interpretera cała pamięć zostaje zwolniona.

  • W jakich okolicznościach problem ten wystąpi podczas wykonywania skryptu?

Wątpię, masz się o co martwić, chyba że masz bardzo niskie limity pamięci lub bardzo dużych dynamicznych struktur danych.Jeśli masz 25 węzłów, które nie są często tworzone/uwalniane, nie będziesz mieć problemu.

  • Will ręcznie niszcząc odniesienia rozwiązać ten problem i mam zawsze to robią?

To pomoże. Podczas ładowania dużego zestawu danych do naszej bazy danych za pomocą Propela natknęliśmy się na duży problem z pamięcią, którą śledziliśmy, aby odwołania kołowe nie były zwalniane. Nasze rozwiązanie polegało na wywołaniu metody, która wyczyściła wszystkie odniesienia.

+0

Jak stworzyłeś tę metodę? Występuje ten sam problem z moją ORM. – andho

+0

Występują tylko problemy podczas testowania, ponieważ w przeciwnym razie skrypty nie są zbyt długie. – andho

+0

Niestety minęło dużo czasu odkąd pracowałem nad Propelem i nie mam już dostępu do kodu. Przepraszam, Andho. – sig11

3

Może i tak, ale ponieważ wyrzuca wszystkie obiekty na koniec każdego wniosku (o ile jesteś buforowanie), nie sądzę, wielu programistów PHP o to martwić.

Jeśli piszesz skrypty wiersza poleceń w PHP, to być może masz powód do martwienia się o to, ale musisz napisać całkiem zawiły kod PHP, zanim stanie się on czymś, o co warto się martwić. A jeśli tak, masz większe problemy.

Powodzenia.

+0

Ponadto istnieje metoda __destruct(). –

2

Biorąc pod uwagę naturę większości stron PHP - to znaczy, że proces jest uruchamiany dla strony internetowej i jest odrzucany po zakończeniu - raczej wątpię, że to jest problem. Nie widziałem wcześniej problemów związanych z odwołaniami cyklicznymi i korzystałem z nich bez problemów. Z mojego doświadczenia wynika, że ​​napotkasz więcej problemów przy zwykłym zużyciu pamięci, ale PHP 5 złagodziło to nieco, odsuwając się od zwykłego kopiowania obiektów i tablic, o ile nie powiedziano inaczej.

2

PHP 5.3 będzie zawierało funkcje wykrywania i niszczenia odwołań cyklicznych. Jest to ustawienie opcjonalne i powinno być używane tylko wtedy, gdy jest to konieczne, ponieważ moduł do zbierania śmieci wykona uderzenie wydajnościowe, ale jest dostosowany do Twojego przykładu.

Opracuj teraz, podejmij środki ostrożności, aby jawnie usunąć dereferencje w metodzie __destruct(), aw miarę możliwości uaktualnij do wersji 5.3.

+3

O ile pamiętam (przed php5.3) __destrukt jest wywoływany tylko wtedy, gdy nie ma żadnych odniesień do pozostawionego obiektu. Dlatego __destruct musiałby zostać jawnie wywołany, jeśli jest częścią okólnika. – dsas

+0

"__destruct" zostanie wywołany jako część "sekwencji zamykania" na końcu skryptu w PHP 5.3. Jednak w tym przypadku sekwencja wywołująca jest losowa (tzn. Można wywołać '__destruct', podczas gdy inne obiekty nadal mają odwołania do tego obiektu). –

Powiązane problemy