2017-12-29 19 views
1

内の参照の問題をクリーンアップし、私はhere参照とPHPでのガベージコレクタを勉強しながら、PHP

$a = array('one'); 
    $a[] =& $a; 
    xdebug_debug_zval('a'); 
    unset($a); 

この時に参照を述べたガベージコレクタと参照のクリーンアップの問題が何であるか理解していませんこのような構造を指す任意の範囲内のシンボルがもはや存在しているが、コードとセクションが

言わなかった配列要素「1」がまだこの同じ配列を指すので、クリーンアップすることができません。それを指す外部シンボルがないので、ユーザーがこの構造をクリーンアップする方法はありません。したがって、メモリリークが発生します。

$a = array('one'); 
    $a[] =& $a; 
    unset($a); 

全体の変数が意志を$:PHPリファレンスを学んだ後、私は未設定の変数は、変数名とコンテンツの間の結合を切る ので、以下のコードに応じたことを意味し

学びましたコンテンツとは関係なく、配列全体が削除されているため、そのコンテンツの参照や変数も削除されるため、クリーンアップの問題はどこにありますか?私が研究し

$a = array('one'); 
    $a[] =& $a; 
    xdebug_debug_zval('a'); 

参考文献:、以下のコードによると、Xdebugの機能がここを生成

ノートは、2つの参照またはポインタまたはバインディングがクリーンアップの問題がないことを証明している解放されることを意味しますFrom:

  1. Manual
  2. Toptal Article
  3. Sitepoint

答えて

0

ポイントはまだVAR $aへのポインタでありますようこれは、削除することはできません、です。このポインタが$aの内部に定義されていることを検出するのは簡単な解決策がないため、$aのために予約されたメモリは使用できません。この画像に見られるように

enter image description here

、アレイ自体の配列内からポインタがあります。このポインタ(refcountをインクリメントする)は、refを$aに設定しないと、存在します。

$a = array('one'); // refcount for a = 1 
$a[] =& $a; // refcount for a = 2 
unset($a); // refcount for a = 1, but there's remains no usable pointer for the php user 

単純なループは、このリファレンスへのポインタが存在しない場合

$start = memory_get_usage(); 

for ($i = 0; $i < 100000; $i++) { 
    $a = ['test']; 
    // if you remove this line, the memory usage is 0, if not 4000000 
    $a[] = &$a; 
    unset($a); 
} 

echo memory_get_usage() - $start; 
+0

PHPは特定の参照からのメモリを解放し、この動作を実証できたので、あなたは、アレイ全体を削除する場合(つまり、第2の参照を保持しています)それからphpはこのzvalコンテナをそれへのポインタとして削除します。親配列が特定のzvalコンテナを指し、同じzvalコンテナを指す要素(子)を持っている場合、子を保持する親を削除した後、相互zvalコンテナへのポインタはありません。クリーンアップの問題はどこですか? – youhana

+0

*したがって、2番目の参照を保持する配列全体を削除すると、phpはこのzvalコンテナをポインタとして削除します*間違っています!まだ配列へのポインタがあり、配列に格納されています – Philipp

関連する問題