Heim  >  Artikel  >  Backend-Entwicklung  >  Probleme im Zusammenhang mit dem PHP-Garbage-Collection-Mechanismus

Probleme im Zusammenhang mit dem PHP-Garbage-Collection-Mechanismus

墨辰丷
墨辰丷Original
2018-06-07 16:41:171358Durchsuche

In diesem Artikel werden hauptsächlich Probleme im Zusammenhang mit dem PHP-Garbage-Collection-Mechanismus vorgestellt. Ich hoffe, dass er für alle hilfreich ist.

Grundlegendes GC-Konzept von PHPDie PHP-Sprache verfügt wie andere Sprachen über einen Garbage-Collection-Mechanismus. Was wir Ihnen heute erklären möchten, hängt mit dem PHP-Garbage-Collection-Mechanismus zusammen. Ich hoffe, es hilft allen. PHP-Strtotime-Anwendungserfahrung PHP-Memory_get_usage() verwaltet den Speicher. PHP-Unset-Probleme bei der Verwendung globaler Variablen. Ausführliche Erklärung. Die Funktion PHP-Unset() zerstört Variablen, um Ihnen beizubringen, wie Sie schnell die Überprüfung der vollständigen PHP-Site-Berechtigungen implementieren können. 1. PHP-Garbage-Collection-Mechanismus (Garbage Collector, als GC bezeichnet). ) Wenn in PHP keine Variablen auf dieses Objekt verweisen, wird dieses Objekt zu Müll. PHP wird es im Speicher zerstören; dies ist der GC-Müllentsorgungsmechanismus von PHP, um einen Speicherüberlauf zu verhindern. Wenn ein PHP-Thread endet, wird der gesamte aktuell belegte Speicherplatz zerstört und alle Objekte im aktuellen Programm werden gleichzeitig zerstört. Der GC-Prozess beginnt im Allgemeinen mit jeder SESSION. Der Zweck von gc besteht darin, die Sitzungsdateien nach ihrem Ablauf automatisch zu zerstören und zu löschen. __destruct /unset __destruct() Der Destruktor wird ausgeführt, wenn das Müllobjekt recycelt wird.
unset zerstört die Variable, die auf das Objekt zeigt, nicht das Objekt. 3. Sitzungs- und PHP-Garbage-Collection-Mechanismus Aufgrund des Arbeitsmechanismus von PHP verfügt es nicht über einen Daemon-Thread, um Sitzungsinformationen regelmäßig zu scannen und festzustellen, ob sie ungültig sind. Wenn eine gültige Anfrage auftritt, verwendet PHP die globalen Variablen session.gc_probability und session Der Wert von .gc_pisor bestimmt, ob ein GC aktiviert werden soll. Standardmäßig bedeutet session.gc_probability=1, session.gc_pisor =100, dass eine Wahrscheinlichkeit von 1 % besteht, einen GC zu starten (d. h. es gibt nur einen GC in 100). Anfragen) Wird mit einer der 100 Anfragen gestartet). . Wenn die Überlebenszeit gc_maxlifetime (Standard 24 Minuten) überschreitet, wird die Sitzung gelöscht.
Wenn Ihr Webserver jedoch über mehrere Sites verfügt, kann GC bei der Verarbeitung von Sitzungen an mehreren Sites zu unerwarteten Ergebnissen führen. Der Grund dafür ist: Wenn GC funktioniert, kann es nicht zwischen Sitzungen verschiedener Sites unterscheiden es lösen?
1. Ändern Sie session.save_path oder verwenden Sie session_save_path(), um die Startrate jeder Site in einem dedizierten Verzeichnis zu speichern verbessert, und die Leistung des Systems wird entsprechend reduziert, was nicht zu empfehlen ist.
3. Bestimmen Sie die Überlebenszeit der aktuellen Sitzung im Code und verwenden Sie session_destroy(), um sie zu löschen.


Grundkenntnisse der ReferenzzählungJede PHP-Variable existiert in einem Variablencontainer namens „zval“, der zusätzlich zum Typ und Wert der Variablen enthält. Enthält auch zwei Bytes mit zusätzlichen Informationen. Das erste ist „is_ref“, ein boolescher Wert, der verwendet wird, um zu identifizieren, ob diese Variable zu einem Referenzsatz gehört. Durch dieses Byte kann die PHP-Engine normale Variablen von Referenzvariablen unterscheiden Mit PHP können Benutzer benutzerdefinierte Referenzen verwenden, indem sie & verwenden. Außerdem gibt es im ZVAL-Variablencontainer einen internen Referenzzählmechanismus, um die Speichernutzung zu optimieren. Das zweite zusätzliche Byte ist „refcount“, das verwendet wird, um den Punkt auf diesen ZVAL-Variablencontainer anzugeben Die Anzahl der Variablen (auch Symbole genannt).

Wenn einer Variablen ein konstanter Wert zugewiesen wird, wird ein zval-Variablencontainer generiert, wie im folgenden Beispiel gezeigt:

  <?php 
  $a = "new string"; 
   
  ?>

Im obigen Beispiel ist die neue Variable eine, die im aktuellen Bereich generiert wird, und in den zusätzlichen zwei Bytes der Informationen wird ein Variablencontainer mit dem Wert „is_ref“ generiert standardmäßig falsch, da keine benutzerdefinierte Referenz generiert wird, da nur eine Variable diesen Variablencontainer verwendet:

  <?php 
  $a = "new string"; 
   
  xdebug_debug_zval(&#39;a&#39;); 
  ?>

Der obige Code wird Ausgabe:

  a: (refcount=1, is_ref=0)=&#39;new string&#39;

Fügen Sie einen Referenzzähler zur Variablen a hinzu

  <?php 
  $a = "new string"; 
   
  $b = $a; 
  xdebug_debug_zval(&#39;a&#39;); 
  ?>

Der obige Code gibt Folgendes aus:

  a: (refcount=2, is_ref=0)=&#39;new string&#39;

Zu diesem Zeitpunkt wird die Die Anzahl der Referenzen beträgt 2, da derselbe Variablencontainer mit Variable a und Variable b verknüpft ist. PHP kopiert den generierten Variablencontainer nicht, wenn dies nicht erforderlich ist. Der Variablencontainer wird zerstört, wenn „refcount“ 0 wird. Wenn a Wenn eine Variable, die leicht einer Variablen zugeordnet werden kann, ihren Gültigkeitsbereich verlässt (z. B. wenn die Funktionsausführung endet) oder die Funktion unset() für die Variable aufgerufen wird, wird der „refcount“ um 1 reduziert. Das folgende Beispiel kann dies veranschaulichen:

  <?php 
  $a = "new string"; 
  $b = $c = $a; 
  xdebug_debug_zval(&#39;a&#39;); 
  unset($b, $c); 
  xdebug_debug_zval(&#39;a&#39;); 
  ?>

Der obige Code gibt Folgendes aus:

  a: (refcount=3, is_ref=0)=&#39;new string&#39; a: (refcount=1, is_ref=0)=&#39;new string&#39;

Wenn wir unset($a) jetzt ausführen, wird der Container, der den Typ und Wert von $ enthält, aus dem Speicher gelöscht

Zusammengesetzte Typen

Bei der Betrachtung zusammengesetzter Typen wie Array und Objekt wird es etwas komplizierter. Im Gegensatz zu skalaren (skalaren) Typwerten speichern Array- und Objekttypen die Variablen ihre Mitglieder oder Eigenschaften in ihrer eigenen Symboltabelle. Das bedeutet, dass das folgende Beispiel drei zval-Variablencontainer generiert

  <?php 
  $a = array(&#39;meaning&#39; => &#39;life&#39;, &#39;number&#39; => 42); 
   
  xdebug_debug_zval(&#39;a&#39;); 
  ?>

Die obige Codeausgabe:

  a: (refcount=1, is_ref=0)=array (&#39;meaning&#39; => (refcount=1, is_ref=0)=&#39;life&#39;, &#39;number&#39; => (refcount=1, is_ref=0)=42)

Die drei zval Variablencontainer sind: a, Bedeutung, Zahl. Die Regeln zum Erhöhen und Verringern der Refcount sind die gleichen wie oben erwähnt

Sonderfall beim Hinzufügen des Arrays selbst als Array-Element:

  <?php 
  $a = array(&#39;one&#39;); 
   
  $a[] = &$a; 
   
  xdebug_debug_zval(&#39;a&#39;); 
  ?>

Das vom obigen Code ausgegebene Ergebnis:

  a: (refcount=2, is_ref=1)=array (0 => (refcount=1, is_ref=0)=&#39;one&#39;, 1 => (refcount=2, is_ref=1)=...)


可以看到数组a和数组本身元素a[1]指向的变量容器refcount为2

当对数组$a调用unset函数时,$a的refcount变为1,发生了内存泄漏

清理变量容器的问题尽管不再有某个作用域中的任何符号指向这个结构(就是变量容器),由于数组元素"1"仍然指向数组本身,所以这个容器不能被消除.因为没有另外的符号指向它,用户没有办法清除这个结构,结果就会导致内存泄漏.庆幸的是,php将在请求结束时清除这个数据结构,但是php清除前,将耗费不少内存空间


回收周期5.3.0PHP使用了新的同步周期回收算法,来处理上面所说的内存泄漏问题

首先,我们先要建立一些基本规则:
如果一个引用计数增加,它将继续被使用,当然就不再垃圾中.如果引用技术减少到零,所在的变量容器将被清除(free).就是说,仅仅在引用计数减少到非零值时,才会产生垃圾周期(grabage cycle).其次,在一个垃圾周期中,通过检查引用计数是否减1,并且检查哪些变量容器的引用次数是零,来发现哪部分是垃圾

2015810114143348.png (429×552)

为避免不得不检查所有引用计数可能减少的垃圾周期,这个算法把所有可能根(possible roots 都是zval变量容器),放在根缓冲区(root buffer)中(用紫色标记),这样可以同时确保每个可能的垃圾根(possible garbage root)在缓冲区只出现一次.仅仅在根缓冲区满了时,才对缓冲区内部所有不同的变量容器执行垃圾回收操作。

总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。

相关推荐:

PHP实现基于SimpleXML生成和解析xml的方法

PHP实现基于XMLWriter操作xml的方法

PHP命名空间、性状与生成器案例详解

Das obige ist der detaillierte Inhalt vonProbleme im Zusammenhang mit dem PHP-Garbage-Collection-Mechanismus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn