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