コピーオンライト (COW とも略される) は、名前が示すように、書き込み時に変更のためにメモリのコピーを実際にコピーします。 COW は、スレッドとメモリの使用量を最適化するために *nix システムで最初に使用され、その後、C++ の STL などのさまざまなプログラミング言語で広く使用されました。 PHP カーネルでは、COW はメインのメモリ最適化方法でもあります。 変数とメモリに関する前述の説明では、参照カウントは変数の破棄とリサイクルにおいて重要な識別の役割を果たします。 参照カウントの目的は、COW が正常に動作できるようにして、メモリを最適に使用できるようにすることです。
コピーオンライトの役割
以下はコードの一部です:
<?php var_dump(memory_get_usage());//先打印出当前内存情况 $arr = array_fill(0, 100000, 'tioncico');//生成一个0-100000键的数组 var_dump(memory_get_usage());//打印内存 $arr_copy = $arr;//把数组赋值给另一个 var_dump(memory_get_usage());//打印内存 $j=1; foreach($arr_copy as $i) {//循环遍历该数组键值查看内存情况 $j += count($i); } var_dump(memory_get_usage());//打印内存
つまり、参照を使用しなくても、PHP変数が値を渡したり値を代入したりする場合、それらはすべて同じメモリを指しますが、$arr_copy の値が変更されるとどうなりますか? <?php
var_dump(memory_get_usage()); //$tipi = array_fill(0, 3, 'php-internal'); //不用array_fill的原因可自己试着打印下 $tipi[0]='php-internal'; $tipi[1]='php-internal'; $tipi[2]='php-internal'; var_dump(memory_get_usage()); $copy = $tipi; xdebug_debug_zval('tipi', 'copy'); var_dump(memory_get_usage()); $copy[0] = '123'; xdebug_debug_zval('tipi', 'copy'); var_dump(memory_get_usage());
結果は次のとおりです: (注: この結果はphp5.6 Web 環境では、php7 リファレンスは異なります)
$arr が $arr_copy に値を代入しても、実行メモリは大幅に変化せず、変化しないことがわかります。後続の foreach traversal でも 5443320 のメモリ量が直接増加します
。なぜなら $arr が $arr_copy に代入されるとき、$arr の値全体がメモリにコピーされるわけではないからです。 , しかし、$arr_copy の値は $arr を指しています。これは、$arr_copy データをフェッチするのと同じですが、$arr が値を格納するメモリをまだ指しています
つまり、参照を使用しなくても、PHP変数は値を渡したり値を代入したりしており、すべて同じメモリを指していますが、$arr_copy の値が変更されたらどうなりますか?
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
結果は次のとおりです: (注: この結果は php5.6 Web 環境でのものであり、php7 の参照は異なります)
$copy[0 ] 値が変更されると、php は $copy[0] にメモリを再適用し、新しい値を割り当てますが、他の値のメモリ状態は影響を受けません。 コピーオンライトの最小粒度は zval 構造です。zval 構造のコレクション (配列やオブジェクトなど) の場合、メモリをコピーする必要がある場合、複雑なオブジェクトは処理のために最小粒度に分解されます。 このようにすると、メモリ内の複雑なオブジェクトの特定の部分が変更されるときに、オブジェクトのすべての要素をメモリ コピーに「分離」する必要がなくなり、メモリの使用量が節約されます。
(記事中のxdebug_debug_zvalはxdebug拡張機能の関数で、変数の参照情報を表示するために使用されます)
以上がphpCOWの仕組みを詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。