ホームページ  >  記事  >  バックエンド開発  >  PHP7のガベージコレクションメカニズムの詳細な説明(GC処理の完全なフローチャート付き)

PHP7のガベージコレクションメカニズムの詳細な説明(GC処理の完全なフローチャート付き)

藏色散人
藏色散人転載
2020-08-25 17:49:295004ブラウズ

ガベージ コレクション:

GC と呼ばれます。その名の通り、廃棄物を再利用することを意味します。
ガベージ コレクション メカニズムについて説明する前に、まずメモリ リークについて触れましょう。

おすすめチュートリアル:「PHP7

メモリリーク:

センスの強い大神様による画像解説:

一般的な意味は、土地を申請してしばらくうんちをし、その後うんちをした後掃除しない場合、その土地は無駄であるとみなされるということです。土地が使用されれば使用されるほど、少なくなればなるほど、最後の土地はうんちでいっぱいになります。最終的には、使用後は忘れずに返却してください。ガベージ コレクションのメカニズムは、ある程度、尻拭いのために使用されます。

C 言語のガベージ コレクションのメカニズム:

C 言語を使用したことがある場合、メモリを確保する方法は malloc または calloc です。このメモリを使い果たした後は、メモリを確保しないでください。忘れてください。無料の機能を使用して解放してください。これは手動のガベージコレクションです。通常、この方法はマスターによって使用されます。

phpの自動ガベージコレクション機構とは何ですか?

まずこの問題について考えてみましょう。php が C 言語で実装されていることは誰もが知っています。 C 言語を使用して統計と変数の解放を実装する方法を考えてみましょう。 C 言語は変数をどのように実装しますか? 変数が宣言されてから最後まで誰も使用しなくなるまで、変数によって占有されていたメモリは解放されます (はガベージ コレクトされました)。

PHP メモリ管理には 2 つのコア アルゴリズムがあります:
1 つは参照カウント、もう 1 つはコピーオンライトです

PHP 変数を宣言する場合 , C言語は以下のようにzvalという構造体を一番下に生成します。

zval {
string "a" //变量的名字是a
value zend_value //变量的值,联合体
type string //变量是字符串类型
}

zval struct構造

(1) phpの変数名を保存 $a
(2) ) php $a
の変数の型 (3) php 変数 $a

の zend_value 共用体 変数に「hello world」などの値 を代入すると、C 言語は一番下 zend_value という共用体(ユニオン)を生成します

zend_value {
string "hello world" //值的内容
refcount 1 //引用计数
}

zend_value Union (union)

(1) php $a hello world
の変数の値を保存します (2) php $a 変数への参照の数を記録します

zval 構造体と zend_value を参照してください。インタビュアーが、php 変数が文字列「123」と数値 123 を保存できる理由を尋ねたら、こうします。どうすればいいかわかりますか?答えられましたか?重要な点は、zval に変数の型が含まれていることです。文字列 123 の場合、型は string で、値は "123" を指します。整数 123 の場合、zval の型は int で、値は "123" を指します。は123です。

参照カウントとは何ですか?

実際のPHP変数参照数の解析コード

$a = 'hello,world';
echo xdebug_debug_zval( 'a');//refcount=1
$b = $a;
echo xdebug_debug_zval( 'a'); //$b引用$a,故变量a,refcount=2
$c = $a;
echo xdebug_debug_zval( 'a'); //$c引用$a,故变量a,refcount=3
unset( $c );
echo xdebug_debug_zval( 'a');//删除了$c的引用,故变量a,refcount=2

実行結果:

a:
(refcount=1, is_ref=0)string 'hello 、world' (length=11)
a:
(refcount=2, is_ref=0)string 'hello,world' (length=11)
a:
(refcount=3, is_ref = 0)文字列 'hello,world' (長さ=11)
a:
(refcount=2, is_ref=0)文字列 'hello,world' (長さ=11)

#コピーコピーとは何ですか?

$a = 'hello';
$b = $a;//$a赋值给$b的时候,$a的值并没有真的复制了一份
echo xdebug_debug_zval( 'a');//$a的引用计数为2
$a = 'world';//当我们修改$a的值为123的时候,这个时候就不得已进行复制,避免$b的值和$a的一样
echo xdebug_debug_zval( 'a');///$a的引用计数为1

実行結果:

a:

(refcount=2, is_ref=0)string 'hello' (length=5)
a:
(refcount=1, is_ref=0)string 'world' (length=5)

実際、$a を $b に代入すると、$a の値は変わりません。本当にコピーを作成しました。これはメモリと時間の計算量に対して非常に失礼です。コンピュータは $b に $a の値を指すだけです。これは高速で経済的と呼ばれます。では、レプリケーションは実際にいつ行われるのでしょうか?つまり、$a の値を 123 に変更する場合、$b の値が $a と同じにならないように、この時点でコピーする必要があります。

参照カウントとコピーオンライトという 2 つの重要な点を簡単なケースを通して説明します。

ガベージ コレクション メカニズム:

zval が設定されていない場合、または関数 (つまりローカル変数) から実行された場合など、これは次のように発生します。 zval と zend_value が切断されています。このとき、zend エンジンが検出する必要があるのは、zend_value の refcount が 0 かどうかです。0 の場合は、コンテンツを直接 KO 解放します。 zend_value の再カウントが 0 でない場合、値は解放できませんが、zend_value がまだゴミである可能性があるため、zend_value が無害であることを意味するわけではありません。

(1) PHP 変数の refcount $a=0 の場合、変数 $a はガベージコレクションされます

(2) PHP 変数の refcount $a>0 の場合、変数 $ a しかし、それはガベージとみなされることもあります。

zend_value の refcount が 0 ではなく、この zend_value がガベージになるのはどのような状況でしょうか?

$arr = [ 1 ];
$arr[] = &$arr;
unset( $arr );

这种情况下,zend_value不会能释放,但也不能放过它,不然一定会产生内存泄漏,所以这会儿zend_value会被扔到一个叫做垃圾回收堆中,然后zend引擎会依次对垃圾回收堆中的这些zend_value进行二次检测,检测是不是由于上述两种情况造成的refcount为1但是自身却确实没有人再用了,如果一旦确定是上述两种情况造成的,那么就会将zend_value彻底抹掉释放内存。

垃圾回收发生在什么时候?

有些同学可能有疑问,就是php不是运行一次就销毁了吗,我要gc有何用?并不是的,首先当一次fpm运行完毕后,最后一定还有gc的,这个销毁就是gc;其次是,内存都是即用即释放的,而不是攒着非得到最后,你想想一个典型的场景,你的控制器里的某个方法里用了一个函数,函数需要一个巨大的数组参数,然后函数还需要修改这个巨大的数组参数,你们应该是函数的运行范围里面修改这个数组,所以此时会发生写时拷贝了,当函数运行完毕后,就得赶紧释放掉这块儿内存以供给其他进程使用,而不是非得等到本地fpm request彻底完成后才销毁。

(1)fpm运行完毕后,最后一定会gc的
(2)运行过程中,也会gc的,内存都是即用即释放的,而不是攒着非得到最后gc

GC处理完整流程图

 

以上がPHP7のガベージコレクションメカニズムの詳細な説明(GC処理の完全なフローチャート付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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