Der Garbage Collector (GC) ist das interne Speicherverwaltungssystem in PHP, aber es gibt einige Feinheiten, die es zu verstehen gilt.
Der GC automatisiert die Speicherverwaltung, wodurch die mühsame Handhabung des Speichers durch manuelle Aufgaben entfällt (was mühsam wäre).
Dadurch können sich Entwickler auf ihre Geschäftslogik konzentrieren, ohne sich übermäßig Gedanken über „Nicht genügend Arbeitsspeicher“-Fehler machen zu müssen.
Natürlich ist es keine Zauberei.
Das Freigeben von Objekten, die nicht mehr benötigt werden, verhindert Speicherverluste.
Der GC verwendet einen Zählmechanismus, um die zu löschenden Elemente zu bestimmen. Wenn keine Referenzen auf ein bestimmtes Objekt verweisen (d. h. $counter = 0), kann dieses Objekt bereinigt werden.
Es funktioniert ziemlich gut, aber einige Referenzen können problematisch sein:
class A { public $b; } class B { public $a; } $a = new A(); $b = new B(); $a->b = $b; $b->a = $a; unset($a); unset($b);
In diesem Fall eines schlechten Designs gibt PHP den Speicher nicht frei, selbst wenn wir $a und $b deaktivieren, da sie aufeinander verweisen, was PHP glauben lässt, dass sie noch verwendet werden.
Glücklicherweise gibt es dafür einen anderen Mechanismus namens Cycle Collector:
gc_collect_cycles();
Grob gesagt durchläuft der Sammler alle Referenzen und wendet einen Algorithmus an, um verwendete Objekte zu markieren, wodurch die zu sammelnden Objekte (die nicht markierten) angezeigt werden.
PHP löst jedoch keine automatische Zyklussammlung aus, bis der Schwellenwert von 10.000 Objekten mit potenziellen zyklischen Referenzen erreicht ist.
Auch hier ist es keine Zauberei, daher müssen Sie gc_collect_cycles() nur in wenigen Fällen aufrufen.
Schlechtes Design kann zu überkomplexen Beziehungen zwischen Objekten führen, was zu mehr Referenzen und häufigerer Speicherbereinigung führt.
Jedes Objekt mit Referenzzählung erfordert zusätzlichen Speicher für seinen Referenzzähler.
Quelle: Wikipedia – Referenzzählung
Der mit Speicherbereinigungsvorgängen verbundene Overhead kann sich erheblich auf die globale Leistung auswirken und letztendlich die Ausführungszeit in bestimmten Szenarien erhöhen.
Vor 10 Jahren erzielte Composer allein durch die Verwendung der Funktion gc_disable() einen enormen Leistungsschub.
Quelle: Composer – GC deaktivieren
Tatsächlich hat PHP 7 den GC drastisch verbessert, sodass er nicht mehr das ist, was er 2014 war.
Darüber hinaus verbesserten PHP 8-Versionen die Speicherzuweisungsstrategien und fügten weitere nützliche Statistiken über GC-Vorgänge zur besseren Überwachung hinzu (gc_status() in 8.3).
Die meisten PHP-Anwendungen sind anforderungsgesteuert und der Speicher wird am Ende der Anforderung automatisch gelöscht.
Wieder ist es ziemlich cool, aber keine Magie. Was passiert mit asynchronen Anfragen und langlebigen Objekten/Daemons?
Irgendwann kann es zu Speicherverlusten kommen.
An diesem Punkt sehen Sie möglicherweise nicht, wie sich der PHP-GC von anderen Sprachen unterscheidet.
Meistens verlassen sich andere Sprachen nicht auf die Referenzzählung, um Müll zu sammeln, oder verwenden möglicherweise andere Implementierungen.
Viele verwenden beispielsweise den Tracing-Algorithmus, der auch ungenutzte Objekte markiert, aber nicht inkrementell arbeitet. Es ist eine Graphendurchquerung.
Außerdem erlauben einige Sprachen keine solche direkte Steuerung (z. B. Ein-/Ausschalten zur Laufzeit).
Wie üblich gibt es einige Vor- und Nachteile, sodass Sie möglicherweise einige hybride Ansätze sehen werden.
Sie können die integrierten gc_*-Helfer nutzen.
Zum Beispiel:
Diese Funktionen sind hilfreich zum Debuggen oder zur Feinabstimmung der Garbage Collection bei Bedarf.
Sie können diesen Beitrag für weitere Einblicke lesen:
PHP 7.4 führte schwache Referenzen ein und PHP 8 führte schwache Karten ein.
Eine schwache Karte könnte als eine Sammlung schwacher Referenzen beschrieben werden.
Diese Datenstruktur ist ein vielseitiger Schlüsselwertspeicher, der PHP hilft, den Überblick über Elemente zu behalten, ohne Unordnung zu schaffen oder übermäßig viel Platz zu beanspruchen.
Sie können es als temporären Speicher betrachten, der sofort gelöscht wird, wenn er nicht mehr benötigt wird, da es keine [starken] Hinweise gibt, die die Speicherbereinigung verhindern könnten:
$object = new stdClass; $map = new WeakMap(); $map[$object] = true; $object->name = 'some name'; print_r($map);// $object is stored in $map unset($object); print_r($map);// $object is cleaned and no longer available
Bei den meisten Verwendungszwecken müssen Sie sich keine Gedanken über die Speicherverwaltung machen, da PHP diese bereits übernimmt.
Da moderne Stacks jedoch langlebige Objekte verwenden, müssen Sie Ihre Anwendung auf mögliche Speicherlecks überwachen.
Wenn Probleme auftreten, müssen Sie möglicherweise den Code optimieren und/oder direkt mit dem GC interagieren.
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3