您好,登錄后才能下訂單哦!
這篇文章主要介紹了PHP寫時復制的案例分析,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
從一個例子說起:
<?php $foo = 1; $bar = $foo; echo $foo + $bar;
變量 $foo 賦值給變量 $bar,這兩個變量具有相同的值,沒有必要新申請內存空間,他們可以共享同一塊內存。在很多場景下PHP 的 COW 對內存進行優化。比如:變量的多次賦值、函數參數傳遞,并在函數體內修改實參等。
什么是“復制”
這是一段摘自鳥哥博客的例子,說的比較清楚,就直接貼過來了。
<?php $var = "laruence"; $var_dup = $var; $var = 1; ?>
很明顯在這段代碼執行以后,$var_dup 的值應該還是”laruence”, 那么這又是怎么實現的呢?這就是 PHP 的 copy on write 機制:
PHP 在修改一個變量以前,會首先查看這個變量的 refcount,如果 refcount 大于1,PHP 就會執行一個分離的例程, 對于上面的代碼,當執行到第三行的時候,PHP 發現 $var 指向的 zval 的 refcount 大于1,那么 PHP 就會復制一個新的 zval 出來,將原 zval 的 refcount 減 1,并修改 symbol_table,使得 $var 和 $var_dup 分離(Separation)。這個機制就是所謂的 copy on write(寫時復制)。
寫時復制應用場景
寫時復制(Copy on Write,也縮寫為COW)的應用場景非常多, 比如Linux中對進程復制中內存使用的優化,在各種編程語言中,如C++的STL等等中均有類似的應用。 COW是常用的優化手段,可以歸類于:資源延遲分配。只有在真正需要使用資源時才占用資源, 寫時復制通常能減少資源的占用。
一個證明 PHP COW 優化內存占用的例子:
<?php $j = 1; var_dump(memory_get_usage()); $tipi = array_fill(0, 100000, 'php-internal'); var_dump(memory_get_usage()); $tipi_copy = $tipi; var_dump(memory_get_usage()); foreach ($tipi_copy as $i) { $j += count($i); } var_dump(memory_get_usage());
運行結果:
$ php t . php int(630904) int(10479840) int(10479944) int(10480040)
內存并沒有顯著提高。
“寫時復制”的原理
多個相同值的變量共用同一塊內存的確節省了內存空間,但變量的值是會發生變化的,如果在上面的例子中, 指向同一內存的值發生了變化(或者可能發生變化),就需要將變化的值“分離”出去,這個“分離”的操作, 就是“復制”。
在PHP中,Zend引擎為了區別同一個zval地址是否被多個變量共享,引入了ref_count和is_ref兩個變量進行標識:
ref_count和is_ref是定義于zval結構體中
is_ref標識是不是用戶使用 & 的強制引用;
ref_count是引用計數,用于標識此zval被多少個變量引用,即COW的自動引用,為0時會被銷毀;
注:由此可見, $a=$b; 與 $a=&$b; 在PHP對內存的使用上沒有區別(值不變化時);
相信大家也可以了解到PHP中COW的實現原理: PHP 中的 COW 基于引用計數ref_count 和 is_ref 實現, 多一個變量指針,就將 ref_count 加 1, 反之減去 1,減到 0 就銷毀; 同理,多一個強制引用 &,就將 is_ref 加 1,反之減去 1。
感謝你能夠認真閱讀完這篇文章,希望小編分享PHP寫時復制的案例分析內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。