ホームページ  >  記事  >  バックエンド開発  >  PHP ガベージ コレクション メカニズム (gc) の概要

PHP ガベージ コレクション メカニズム (gc) の概要

尚
転載
2020-03-27 09:17:132859ブラウズ

PHP ガベージ コレクション メカニズム (gc) の概要

PHP コンパイル原則:

ze (zend エンジン) は字句アナライザーを呼び出して PHP コードからスペースを削除し、コメントの後のトークンに分割し、構文を呼び出します。分析 次に、プロセッサはトークンを処理して op 配列の形式で存在する opcode を形成し、最後に op 配列を実行して結果を出力します。

PHP スレッドが終了すると、現在占有されているすべてのメモリ領域が破棄されます。では、このスレッドが終了しない場合、どうやってメモリを再利用すればよいのでしょうか?

refcount: 参照テクノロジ デバイス。コンテナを指すポインタの数として理解できます。

is_ref: 参照の有無(0か1のみ)

代入処理:

<?php

$a = &#39;aa&#39;;
   
xdebug_debug_zval(a);  //(refcount=1, is_ref=0),string &#39;aa&#39; (length=6)

$b = $a; 

//以下的两个其实是一个变量容器

xdebug_debug_zval(a); //(refcount=2, is_ref=0),string &#39;aa&#39; (length=6)
xdebug_debug_zval(b); //(refcount=2, is_ref=0),string &#39;aa&#39; (length=6)

unset($b);  //对变量容器 refcount 减1xdebug_debug_zval(a); //(refcount=1, is_ref=0),string &#39;aa&#39; (length=6)
xdebug_debug_zval(b); //b: no such symbol  b变量被销毁,指向被断掉,如果对应容器的引用技术为零,那么该块儿内存被回收


$b = $a;

$b = &#39;bb&#39;;

xdebug_debug_zval(a); //(refcount=1, is_ref=0),string &#39;aa&#39; (length=6)
xdebug_debug_zval(b); //(refcount=1, is_ref=0),string &#39;aa&#39; (length=6)  重新申请一个变量容器存储b,a的变量容器引用减1

参照処理:

<?php

$a = &#39;aa&#39;;

xdebug_debug_zval(&#39;a&#39;);  //(refcount=1, is_ref=0),string &#39;aa&#39; (length=2)

$b = & $a;//变量容器的引用技术加1,引用标记置为1xdebug_debug_zval(&#39;a&#39;);  //(refcount=2, is_ref=1),string &#39;aa&#39; (length=2)
xdebug_debug_zval(&#39;b&#39;);  //(refcount=2, is_ref=1),string &#39;aa&#39; (length=2)


$b = &#39;123&#39;; 

//php会发现,该容器变量是引用(is_ref),所以容器变量不用像赋值那样再申请一个

xdebug_debug_zval(&#39;a&#39;);  //(refcount=2, is_ref=1),string &#39;123&#39; (length=2)
xdebug_debug_zval(&#39;b&#39;);  //(refcount=2, is_ref=1),string &#39;123&#39; (length=2)


unset($b);//变量容器应用计数减1,引用为零

xdebug_debug_zval(&#39;a&#39;);  //(refcount=1, is_ref=0),string &#39;123&#39; (length=2)
xdebug_debug_zval(&#39;b&#39;); // b: no such symbol

他にもある場合1 つの参照の設定を解除すると、is_ref はゼロに設定されますか? その場合、バグは発生しませんか?変数コンテナは依然として参照です。それでは見てみましょう:

<?php


$a = &#39;aa&#39;;

$b = &$a;
$c = &$a;//可以看到引用refCount是3,is_ref永远是1xdebug_debug_zval(&#39;a&#39;); //(refcount=3, is_ref=1),string &#39;aa&#39; (length=2)
xdebug_debug_zval(&#39;b&#39;); //(refcount=3, is_ref=1),string &#39;aa&#39; (length=2)
xdebug_debug_zval(&#39;c&#39;); //(refcount=3, is_ref=1),string &#39;aa&#39; (length=2)


unset($b);//我们期待的bug没有出现,只是refcount减1,is_ref还是1xdebug_debug_zval(&#39;a&#39;); //(refcount=2, is_ref=1),string &#39;aa&#39; (length=2)
xdebug_debug_zval(&#39;b&#39;); // b: no such symbol
xdebug_debug_zval(&#39;c&#39;); //(refcount=2, is_ref=1),string &#39;aa&#39; (length=2)

//那php它怎么知道这个容器还有引用,毕竟is_ref仍然是1,不能计数,那么现在refcount就起作用了,是它告诉php,该变量有几个引用,但问题又来了,如果我干点坏事,在引用的时候,又赋值,它会不会有bug

$e = $a;//我们看到期望的bug还是没出现,这时候再赋值,就不像直接赋值那么简单refcount加1了,而是申请了一个新的变量容器

xdebug_debug_zval(&#39;a&#39;); //(refcount=2, is_ref=1),string &#39;aa&#39; (length=2)
xdebug_debug_zval(&#39;e&#39;); //(refcount=1, is_ref=0),string &#39;aa&#39; (length=2)

変数の設定解除と null の代入は再利用できますか?多くの人は、これら 2 つが変数スペースをリサイクルできると誤解しています。実際、それらは間違っています。null は、変数によって占有されるスペースを減らすだけです。リサイクルの観点から見ると、コンテナはまだ存在します。

<?php

$a = &#39;aa&#39;;

$b = $a;

$b = null;

//又申请了一个变量容器
xdebug_debug_zval(&#39;a&#39;);  //(refcount=1, is_ref=0),string &#39;aa&#39; (length=2)
xdebug_debug_zval(&#39;b&#39;);  //(refcount=1, is_ref=0),null   变量空间并没被回收

unset($b);

//这时候才释放了b变量容器的空间
xdebug_debug_zval(&#39;a&#39;);  //(refcount=1, is_ref=0),string &#39;aa&#39; (length=2)
xdebug_debug_zval(&#39;b&#39;);  //b: no such symbol

推奨: PHP ビデオ チュートリアル

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

声明:
この記事はoschina.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。