Maison  >  Article  >  développement back-end  >  Problèmes liés au mécanisme de récupération de place PHP

Problèmes liés au mécanisme de récupération de place PHP

墨辰丷
墨辰丷original
2018-06-07 16:41:171289parcourir

Cet article présente principalement les problèmes liés au mécanisme de récupération de place PHP. Les amis intéressés peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

Concept GC de base de PHPLe langage PHP, comme d'autres langages, dispose d'un mécanisme de récupération de place. Donc, ce que nous voulons vous expliquer aujourd'hui est lié au mécanisme de garbage collection PHP. J'espère que cela aide tout le monde. Expérience de l'application PHP strtotime PHP memory_get_usage() gère la mémoire Explication détaillée des problèmes d'utilisation des variables globales PHP non définies La fonction PHP unset() détruit les variables pour vous apprendre à implémenter rapidement la vérification complète des autorisations du site PHP 1. Mécanisme de récupération de place PHP (Garbage Collector, appelé comme GC) en PHP, lorsqu'aucune variable ne pointe vers cet objet, cet objet devient un déchet. PHP le détruira en mémoire ; il s'agit du mécanisme d'élimination des déchets GC de PHP pour empêcher le débordement de mémoire. Lorsqu'un thread PHP se termine, tout l'espace mémoire actuellement occupé sera détruit et tous les objets du programme en cours seront détruits en même temps. Le processus GC commence généralement à s'exécuter à chaque SESSION. Le but de gc est de détruire et de supprimer automatiquement les fichiers de session après leur expiration. 2. __destruct /unset __destruct() Le destructeur est exécuté lorsque l'objet poubelle est recyclé.
unset détruit la variable pointant vers l'objet, pas l'objet. 3. Mécanisme de récupération de place de session et PHP En raison du mécanisme de fonctionnement de PHP, il ne dispose pas de thread démon pour analyser régulièrement les informations de session et déterminer si elles sont invalides. Lorsqu'une requête valide se produit, PHP utilisera les variables globales session.gc_probability. et session La valeur de .gc_pisor détermine s'il faut activer un GC. Par défaut, session.gc_probability=1, session.gc_pisor =100 signifie qu'il y a 1% de possibilité de démarrer un GC (c'est-à-dire qu'il n'y a qu'un gc sur 100). requêtes) Sera démarré avec l'une des 100 requêtes). Le travail du mécanisme de récupération de place PHP consiste à analyser toutes les informations de session, à soustraire l'heure de la dernière modification de la session de l'heure actuelle et à la comparer avec le paramètre session.gc_maxlifetime. . Si le temps de survie dépasse gc_maxlifetime (24 minutes par défaut), la session sera supprimée.
Cependant, si votre serveur Web possède plusieurs sites, GC peut avoir des résultats inattendus lors du traitement de sessions sur plusieurs sites. La raison en est que lorsque GC fonctionne, il ne fera pas de distinction entre les sessions de différents sites. le résoudre ?
1. Modifiez session.save_path, ou utilisez session_save_path() pour enregistrer la session de chaque site dans un répertoire dédié
2. Fournissez le taux de démarrage de GC Naturellement, le taux de démarrage du mécanisme de récupération de place PHP. amélioré et les performances du système seront également réduites en conséquence et ne sont pas recommandées.
3. Déterminez la durée de survie de la session en cours dans le code et utilisez session_destroy() pour la supprimer.


Connaissance de base du comptage de référencesChaque variable PHP existe dans un conteneur de variables appelé "zval". Un conteneur de variables zval, en plus de contenir le type et la valeur de la variable, comprend également deux octets d'informations supplémentaires. Le premier est "is_ref", qui est une valeur booléenne utilisée pour identifier si cette variable appartient à un ensemble de référence. Grâce à cet octet, le moteur PHP peut distinguer les variables ordinaires des variables de référence. PHP permet aux utilisateurs d'utiliser des références personnalisées en utilisant &, il existe également un mécanisme de comptage de références interne dans le conteneur de variables zval pour optimiser l'utilisation de la mémoire. Le deuxième octet supplémentaire est "refcount", qui est utilisé pour indiquer le point vers ce conteneur de variables zval. Le nombre de variables (également appelées symboles).

Lorsqu'une variable se voit attribuer une valeur constante, un conteneur de variables zval sera généré, comme le montre l'exemple suivant :

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


Dans l'exemple ci-dessus, la nouvelle variable est a, qui est générée dans la portée actuelle. Et un conteneur de variable de type chaîne et de valeur « nouvelle chaîne » est généré dans les deux octets d'informations supplémentaires, « is_ref » est défini. sur false par défaut car aucune référence personnalisée n'est générée. "refcount" est défini sur 1 car il n'y a qu'une seule variable utilisant ce conteneur de variables :

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


Le Le code ci-dessus affichera :

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


Ajoutez un nombre de références à la variable a

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


Le code ci-dessus affichera :

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


À l'heure actuelle, le nombre de références est de 2, car le même conteneur de variables est associé à la variable a et à la variable b. PHP ne copiera pas le conteneur de variables généré lorsque ce n'est pas nécessaire. Le conteneur de variables est dans "refcount. " Il est détruit lorsqu'il devient 0. Lorsqu'une variable associée à une certaine variable quitte sa portée (par exemple : l'exécution de la fonction se termine), ou que la fonction unset() est appelée sur la variable, "refcount" sera réduit de 1. , comme suit Un exemple peut illustrer :

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


Le code ci-dessus affichera :

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


Si nous exécutons maintenant unset($a), le type et la valeur contenue dans $ Le conteneur sera supprimé de la mémoire

Types composés

Les choses deviennent un peu plus compliquées lorsque l'on considère les types composés comme le tableau et l'objet contrairement au type scalaire. les valeurs, les tableaux et les variables de type objet stockent leurs membres ou propriétés dans leurs propres tables de symboles. Cela signifie que l'exemple suivant générera trois conteneurs de variables zval

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


La sortie de code ci-dessus :

  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)


Les trois conteneurs de variables zval sont : a, ce qui signifie nombre. Les règles d'augmentation et de diminution du nombre de refcount sont les mêmes que celles mentionnées ci-dessus


Cas particulier, lors de l'ajout du nombre de refcount. tableau lui-même en tant qu'élément du tableau :

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


Le résultat généré par le code ci-dessus :

  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命名空间、性状与生成器案例详解

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn