//array_fill はここではもう使用されていません パディング、なぜですか?
$tipi[0] = 'php-internal';
$tipi[1] = 'php-internal';
var_dump(memory_get_usage());コピー = $tipi;
var_dump(memory_get_usage());
$copy[0] = 'tipi', 'copy'; ;
var_dump(memory_get_usage());
//-----実行結果-----
$ php t.php
int(629384)
tipi: (refcount=2, is_ref=0)=array (0 => (refcount=1, is_ref=0)='php-internal',
2 => (refcount= 1, is_ref=0)='php-internal')
コピー: (refcount=2、 is_ref=0)=array (0 => (refcount=1, is_ref=0)='php-internal',
=> (refcount=1, is_ref=0)='php-internal',
int( 629512) 2 =1, is_ref=0)=array (0 => (refcount=1, is_ref=0)='php-internal', ,
2 = & gt; (Refcount = 2, is_ref = 0) = 'php-internal')
copy:(refcount = 1、is_ref = 0)= array(0 =>(refcount = 1、is_ref = 0)= 'php-internal'、
;(refcount = 2、is_ref =0)='php-内部')
int(630088)
この例では、次の機能が見つかります:
$copy = $tipi; この基本的な割り当て操作は COW のメモリの「共有」をトリガーし、メモリのコピーを生成しません。
COW の粒度は zval 構造です。PHP のすべての変数は zval に基づいているため、メモリが必要な場合、COW のスコープは zval 構造で構成されるすべての変数になります。コピーする場合、オブジェクトは最小の粒度に分割されて処理されます。これにより、オブジェクトのすべての要素をメモリ コピーに「個別にコピー」することなく、メモリ内の複雑なオブジェクトの特定の部分を変更できます。
コードをコピーします
コードは次のとおりです:
array_fill() は、配列を埋めるときに COW 戦略も使用します。これは、この例のデモに影響を与える可能性があります。興味のある方は、$PHP_SRC/ext/standard/array.c の PHP_FUNCTION(array_fill) の実装を参照してください。
xdebug_debug_zval() は xdebug 拡張機能の関数で、zend 内の変数の参照情報を出力するために使用されます。 xdebug 拡張機能がインストールされていない場合は、代わりに debug_zval_dump() を使用できます。 参考: http://www.php.net/manual/zh/function.debug-zval-dump.php
コピーオンライトを実装する
上の 3 つの例を見て、相信大家も PHP 内の COW の実現原理を理解することができます。PHP 内の COW は参照数ref_count と is_ref实现、多一变量指针、就将ref_countadd1、反之减去1、 0 に減らされると破棄されます。同様に、もう 1 つ必須の参照 & がある場合、is_ref は 1 増加され、そうでない場合は 1 減少されます。
典型的な例を次に示します:
コードをコピーします コードは次のとおりです:
$foo = 1;
$bar = $foo'); 'foo')
: (refcount=2, is_ref=0)=1
foo: (refcount=1, is_ref=0)=1
変数の章を前に紹介した後、$foo に値が割り当てられるとき、$foo 変数の値は $foo 変数によってのみ指されることがわかりました。 $foo の値が $bar に割り当てられると、PHP はメモリを $bar にコピーしませんが、$foo と $bar が同じアドレスを指すようにします。同時に、参照カウントが 1 増加し、新しい 2 になります。続いて、$bar の値を変更します。このとき、$bar 変数が指すメモリが直接必要な場合は、それに応じて $foo の値も変更されます。これは私たちが望む結果ではありません。したがって、PHP カーネルはメモリをコピーし、その値を割り当てられた値 2 に更新します (この操作は変数分離操作とも呼ばれます)。同時に、元の $foo 変数が指すメモリは によってのみ指されます。 $foo なので、参照カウントは :refcount=1 に更新されます。
単純そうに見えますが、& 演算子の存在により、実際の状況はさらに複雑になります。以下の例を参照してください:
図6.6 &演算子>によるメモリコピー分離
この例から、PHP での問題が発生しやすい & 演算子の処理がわかります。 $beauty=&$pan; の場合、両方の変数は本質的に参照型になり、その結果、一見普通の変数 $pan が & と同じように動作します。 $pan は一部の内部処理で使用され、特に配列要素内の参照変数を使用すると、問題が発生しやすくなります。 (最後の例を参照)
作業のほとんどはテキスト処理であり、変数はキャリアです。さまざまなタイプの変数が PHP のライフサイクルを通じて実行されます。変数の COW 戦略には、Zend エンジンの変数とそのメモリの処理も反映されます。ソースコードファイル関連コンテンツを参照してください:
コードをコピーします
コードは次のとおりです:
Zend/zend_execute.c
========================== ==== ========= zend_assign_to_variable_reference(); zend_assign_to_object(); //次のマクロ定義の使用ゼンド.h
=== =====================================
#define Z_REFCOUNT(z) Z_REFCOUNT_P(&(z) )
#define Z_SET_REFCOUNT(z, rc) (&(z))
#define Z_ISREF (Z) REF_P (& (Z))
#Z_SET_ISREF (Z) Z_SET_ISREF_P (& (Z)) を定義します
#Z_UNSET_ISREF (Z) z_isref_p (& (& (& (z)) を定義) #z_Set_isref_to (z, isref) を定義 z_Set_isref_to_p (&(z), isref)
最後に、引用符は慎重に使用してください&
前述の変数の参照カウントと PHP での参照は同じものではありません。参照は C 言語のポインタに似ており、C 命令の柔軟性や制限がありません。
PHP には予期せぬ動作が多数あり、互換性を破壊できない歴史的な理由により、当面は修正しないことを選択するものや、使用シナリオが少ないものもあります。 PHP では、これらの罠を回避することしかできません。たとえば、次の例を考えてみましょう。
参照演算子は PHP の COW 戦略の最適化につながるため、参照を使用するには、誤用を避け、理解しにくいバグを回避するために、参照の動作を明確に理解する必要があります。 PHP の参照について十分に理解していると思われる場合は、次の例を説明してみてください:
コードをコピーします コードは次のとおりです:
$foo['love'] = 1;
$bar = &$foo['love'];
$tipi = $ foo;
$tipi['love'] = '2'
echo $foo['love'];
この例では、最後に 2 が出力されます。$tipi が $foo 変数と $bar 変数の参照操作にどのような影響を与え、$foo['love'] 汚染を参照に変え、Zend が $ を汚染しないかに誰もが非常に驚くでしょう。 tipi[ 'love'] の変更により、コピー分離されたメモリが生成されます。
http://www.bkjia.com/PHPjc/769673.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/769673.html技術記事始める前に、簡単なコードを見てみましょう。 以下のようにコードをコピーします。 ?php //例 1 $foo = $foo; このコードを実行します。番号を取得します...
を印刷します