ホームページ  >  記事  >  バックエンド開発  >  PHP ガベージ コレクション メカニズムがメモリ リークを処理する方法の詳細な分析_PHP チュートリアル

PHP ガベージ コレクション メカニズムがメモリ リークを処理する方法の詳細な分析_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-21 15:06:34767ブラウズ

前回は refcount と is_ref について話しましたが、ここではメモリ リークについて話しましょう

コードをコピーします コードは次のとおりです:

$a = array(1, 2, &$a);
unset($ a);

古いPHPバージョンでは、ここでメモリリークが発生します。 解析は以下の通りです:

最初の行を実行すると、zval refcount=2とis_ref=1が$aと$a[2]で指されていることが分かります

次に2行目を実行すると、$aがシンボルテーブルから削除され、同時にzvalのrefcount--を指します。このとき、refcount!=0なので、zvalはrefcount=1になります。ガベージコレクションとして扱われませんが、このとき、このzvalを指す$a[2]のエントリが失われ、このzvalはメモリのゴミとなってしまいました

同じことがクラスの内部参照でも起こります。たとえば

コードをコピーコードは次のとおりです:

$a = new Man();
$a->self = &$a ;
unset ($a);

では、この問題を解決するには、新しい GC メカニズムがアルゴリズムを使用します

PHP には、zval ノード情報を保存するためのルート バッファーがあり、ルート バッファーがいっぱいになるか、gc 関数が手動で呼び出されると、GC アルゴリズムが開始されます

配列またはクラス型 zval の場合、ガベージ コレクション メカニズムが開始されると、アルゴリズムはクラス内の zval 配列/要素/メンバーの zval を走査し、refcount を 1 ずつ減分します。 zval が 0 に減らされるということは、zval がメモリのゴミであり、破棄されることを意味します。以下の例を参照してください

コードをコピーします コードは次のとおりです:

$a = array(1) , 2, &$a, &$a);
unset($a);

z1のrefcount=3、is_ref=1と仮定すると、$aが指すzvalを知るのは簡単です

unset($a)を実行すると、シンボルテーブルから$aが削除され、z1へのアクセスも失われます

GC が開始されると、z1 の配列要素の zval の refcount がトラバースされて 1 減算されます。 a[2] にトラバースする場合は z1 refcount--、a[3] が z1 refcount-- の場合、この時点で時間 z1 refcount = 0、z1 はメモリのゴミとしてマークでき、アルゴリズムの後にリサイクルされます

要約すると、次のように表現できます: 配列型 zval がある場合、その要素 zval が 1 回走査され、refcount=0 の最後の zval がガベージである場合、走査された zval-- の refcount が使用されます。リサイクルする必要があります

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/327624.html技術記事前回は refcount と is_ref について説明しましたが、ここでメモリ リークについて説明します。 $a = array(1, 2, unset($a); 古いバージョンの PHP では、ここでメモリ リークが発生します。 ..
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。