Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erklärung des GC-Mechanismus in PHP

Detaillierte Erklärung des GC-Mechanismus in PHP

*文
*文Original
2017-12-27 14:12:384259Durchsuche

In diesem Artikel wird hauptsächlich die Interpretation des Garbage-Collection-Mechanismus in PHP vorgestellt. Ob er über eine GC-Funktion verfügt, ist ein wichtiges Anliegen bei der Entwicklung einer Programmiersprache. Ich hoffe, es hilft allen.

Grundlegendes GC-Konzept von PHP
Die 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 Detaillierte Erläuterung der Probleme bei der Verwendung globaler PHP-Unset-Variablen 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, siehe als GC) in PHP: Wenn 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 speziellen 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ählung
Jede PHP-Variable existiert in einem Variablencontainer namens „zval“, der zusätzlich den Typ und den Wert von enthält Die Variable enthält außerdem zwei Bytes mit zusätzlichen Informationen. Das erste ist „is_ref“, ein boolescher Wert, der angibt, ob diese Variable zu einem Referenzsatz gehört. Über dieses Byte kann die PHP-Engine gewöhnliche Variablen und Referenzen kombinieren Da PHP es Benutzern ermöglicht, benutzerdefinierte Referenzen zu verwenden, gibt es im zval-Variablencontainer auch einen internen Referenzzählmechanismus, um die Speichernutzung zu optimieren Zeiger darauf Die Anzahl der Variablen (auch Symbole genannt) im zval-Variablencontainer

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 a, die im aktuellen Bereich generiert wird von string und einem Variablencontainer mit dem Wert „new string“. In den zusätzlichen zwei Bytes an Informationen ist „is_ref“ standardmäßig auf „false“ gesetzt, da keine benutzerdefinierte Referenz generiert wird, da nur A vorhanden ist Variable verwendet diesen Variablencontainer. Rufen Sie xdebug auf, um den Variableninhalt anzuzeigen:


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


Der obige Code gibt Folgendes aus:


  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 beträgt die Anzahl der Referenzen 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. „refcount“ wird zu 0. Wenn eine mit einer bestimmten Variablen verknüpfte Variable 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 veranschaulicht:


<?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 jetzt unset($a) ausführen, wird der Container, der den Typ und Wert $ enthält, aus dem Speicher gelöscht

Zusammengesetzte Typen (Compound-Typen)

Wenn es etwas komplizierter wird, wenn man zusammengesetzte Typen wie Array und Objekt betrachtet, speichern Variablen vom Typ Array und Objekt ihre Mitglieder oder Eigenschaften in ihrer eigenen Symboltabelle Das Beispiel generiert drei Zval-Variablencontainer


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

以上代码输出:


  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)

这三个zval变量容器是:a,meaning,number.增加和减少refcount的规则和上面提到的一样


特例,添加数组本身作为数组元素时:


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

以上代码输出的结果:


  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底层分析的视频和课件分享

浅析PHP底层的运行机制和工作原理

PHP底层工作原理_PHP教程


Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung des GC-Mechanismus in PHP. 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