Mailinglisten-Archive |
Hi, On Monday 26 September 2005 14:59, Andre Manikofski wrote: > Wenn ich ein lägeres Skript programmiert habe und während der > Programmierung im Quelltext mit UNSET ()- Variablen freigegebe, wird dann > in Echtzeit "quasi" Speicher frei oder wird dies erst am Ende eines > Skripten durch den PHP- Interpreter vollzogen? Kurze Antwort: Ja, beides. Etwas längere Antwort: Zunächst musst Dir die Grundlegende Geschichte bzgl. refcount klar machen: Die Zuweisung $a = $b; führt nicht zu einem doppelten Speicherverbrauch. Stattdessen wird in der Variablentabelle ein neuer Eintrag angelegt, der auf eine existierenden Variablenspeicher in diesem Speicherbereich (dem sogenannten zval) wird ein Flag "refcount" hochgesetzt erst bei Zuweisung eines neuen Werts auf eine Variable wird die separiert und der neue Speicher belegt. Damit unset was bringen kann müssen alle internen Referenzen auf eine Variable entsorgt werden. Dann wird der Speicher wieder freigegeben - ah so einfach ist das dann auch wieder nicht. Da das anfordern von neuem Speicher vom Betriebssystem recht lange dauert gibt es da (insbesondere in jüngeren Versionen) wieder Optimierungen, namentlich den Zend Memory Manager, die dafür sorgen, dass der Speicher nicht unnötig freigegeben und dann gleich wieder angefordert wird. Aber er wird auch wieder freigegeben, evtl. etwas Zeitversetzt in größerer Menge. Wenn Du also größere Datenstrukturen freigibst kann das sehr wohl was bringen. Hier und da ne einzelne Variable bringt fast nichts... Falls Dein Skript über längere Zeit (Tage?) läuft gibt es noch ein paar Fallstricke die zu stetig wachsendem Speicherverlauf führen können. a) Bugs und b) kleinere leaks die schwer zu tracken sind und von den Entwicklern als nicht so tragisch angesehen werden. Zur letzteren Gruppe fällt mir ein knappes PHP 5 Beispiel ein: <?php try { while ($a != 42) { // ... throw new Exception("blubber"); // ... } } catch (Exception $e) { ... } ?> hier wird, durch die Exception aus der while-Schleife herausgesprungen. Da bleiben wenige Byte interne Arbeitsdaten der while-Schleife unaufgeräumt. Dies wird als weniger kritisch angesehen, da eine Exception ienen Ausnahme-Zustand bedeutet der, so man Exceptions nicht für Control-Flow missbraucht, nicht sonderlich oft auftreten sollte. Komplett aufgeräumt wird am Skriptende. (Nungut, auch nicht 100%ig da kann es unter ungünstigen Umständen usw. auch mal den ein oder anderen Bug, insbesondere in externen libs¹, geben der zu einem leak führt...) Hoffe etwas geholfen zu haben, johannes [¹] Das mit den externen libs hängt nicht damit zusammen, dass die PHP Entwickler besonders toll und die anderen schlecht sind sondern, dass PHP/die Zend Engine einen Mechanismus hat, der sich merkt welcher Speicher für die Skript-Verarbeitung eines Requests angefordert wird und wenn da irgendwo der free vergessen wurde am Request-Ende einspringt. Dieser Mechanismus wird aber i.d.R. nicht von externen libs genutzt (und als Nebenbemerkung: nur über diesen Mechanismus angeforderter Speicher zählt bei memory_limit&co)
php::bar PHP Wiki - Listenarchive