ホームページ  >  記事  >  バックエンド開発  >  PHP ガベージ コレクション メカニズムに関連する問題

PHP ガベージ コレクション メカニズムに関連する問題

墨辰丷
墨辰丷オリジナル
2018-06-07 16:41:171354ブラウズ

この記事では主に PHP のガベージ コレクション メカニズムに関する問題を紹介します。興味のある方はぜひ参考にしてください。

PHP の基本的な GC 概念PHP 言語には、他の言語と同様に、ガベージ コレクション メカニズムがあります。したがって、今日説明したいことは、PHP ガベージ コレクション メカニズムに関連するものです。お役に立てれば幸いです。 PHP strtotime アプリケーションのエクスペリエンス PHPmemory_get_usage() によるメモリの管理 PHP unset グローバル変数の使用問題の詳細な説明 PHP unset() 関数は変数を破棄して、PHP の完全なサイト権限検証を迅速に実装する方法を学習します 1. PHP ガベージ コレクション メカニズム (ガベージ コレクター、GC と呼ばれます) ) PHP では、このオブジェクトを指す変数がない場合、このオブジェクトはガベージになります。 PHP はこれをメモリ内で破棄します。これは、メモリのオーバーフローを防ぐための PHP の GC ガベージ処理メカニズムです。 PHP スレッドが終了すると、現在占有されているすべてのメモリ領域が破棄され、現在のプログラム内のすべてのオブジェクトが同時に破棄されます。 GC プロセスは通常、セッションごとに実行を開始します。 gc の目的は、セッション ファイルが期限切れになった後に自動的に破棄して削除することです。 2. __destruct /unset __destruct() ガベージ オブジェクトがリサイクルされるときにデストラクターが実行されます。
unset は、オブジェクトではなく、オブジェクトを指す変数を破棄します。 3. セッションと PHP のガベージ コレクション メカニズム PHP の動作メカニズムにより、セッション情報を定期的にスキャンしてセッション情報が無効かどうかを判断するデーモン スレッドがありません。有効なリクエストが発生した場合、PHP はグローバル変数 session.gc_probability を使用します。デフォルトでは、session.gc_probability=1、session.gc_pisor =100 は、GC が開始される可能性が 1% であることを意味します (つまり、GC は 100 個に 1 つだけです)。 PHP ガベージ コレクション メカニズムの仕事は、すべてのセッション情報をスキャンし、現在の時刻からセッションの最終変更時刻を減算し、それを session.gc_maxlifetime パラメーターと比較することです。生存時間が gc_maxlifetime (デフォルトは 24 分) を超えると、セッションは削除されます。
ただし、Web サーバーに複数のサイトがある場合、セッションの処理時に GC が予期しない結果を引き起こす可能性があります。その理由は、GC が動作している場合、異なるサイトのセッションが区別されないためです。
1. session.save_path を変更するか、session_save_path() を使用して各サイトのセッションを専用のディレクトリに保存します。 当然ながら、PHP のガベージ コレクション メカニズムの起動速度は次のようになります。改善され、システムのパフォーマンスもそれに応じて低下するため、お勧めできません。
3. コード内で現在のセッションの生存時間を確認し、session_destroy() を使用して削除します。


参照カウントの基礎知識各 PHP 変数は、変数の型と値に加えて、「zval」と呼ばれる変数コンテナーに存在します。 1 つ目は、この変数が参照セットに属しているかどうかを識別するために使用されるブール値です。このバイトを通じて、PHP エンジンは通常の変数と参照変数を区別できます。 PHP では、ユーザーが & を使用してカスタム参照を使用できます。zval 変数コンテナには、メモリ使用量を最適化するための内部参照カウント メカニズムもあります。これは、この zval 変数コンテナへのポイントを示すために使用される「refcount」です。変数 (シンボルとも呼ばれます) の数。

変数に定数値が割り当てられると、次の例に示すように、zval 変数コンテナが生成されます。

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

上記の例では、新しい変数は現在のスコープで生成され、型が文字列、値が「new string」の変数コンテナが生成され、追加の 2 バイトの情報が「is_ref」に設定されます。カスタム参照は生成されないため、デフォルトでは false になります。この変数コンテナを使用する変数が 1 つだけであるため、「refcount」は 1 に設定されます。変数の内容を表示するには、xdebug を呼び出します。出力:

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

変数 a

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

に参照カウントを追加します。上記のコードは出力します:

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

この時点で、数値変数 a と変数 b には同じ変数コンテナが関連付けられているため、PHP は生成された変数コンテナを必要のないときにコピーしません。変数コンテナは "refcount" が 0 になると破棄されます。変数に簡単に関連付けられている変数がそのスコープを離れる (例: 関数の実行が終了する) か、変数に対して unset() 関数が呼び出されると、「refcount」が 1 減ります。次の例で説明します。

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

上記のコードは次のように出力します:

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

#ここで unset($a) を実行すると、$ の型と値を含むコンテナがメモリから削除されます

複合型

配列やオブジェクトなどの複合型を考慮すると、スカラー (スカラー) 型の値とは異なり、配列やオブジェクト型は変数に格納されます。これは、次の例が 3 つの zval 変数コンテナを生成することを意味します。

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

上記のコード出力:

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

3 つの zval 変数コンテナは: a、意味、数値です。refcount を増減するルールは上記と同じです。

配列自体を配列要素として追加する場合の特殊なケース:

  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)

上記のコード出力の結果:

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

以上がPHP ガベージ コレクション メカニズムに関連する問題の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。