什麼是寫時複製(copy on write)?
答:在複製乙個物件的時候並不是真正的把原先的物件複製到記憶體的另外乙個位置上,而是在新物件的記憶體對映表中設定乙個指標,指向源物件的位置,並把那塊記憶體的copy-on-write位設定為1.這樣,在對新的物件執行讀操作的時候,記憶體資料不發生任何變動,直接執行讀操作;而在對新的物件執行寫操作時,將真正的物件複製到新的記憶體位址中,並修改新物件的記憶體對映表指向這個新的位置,並在新的記憶體位置上執行寫操作。
這個技術需要跟虛擬記憶體和分頁同時使用,好處就是在執行複製操作時因為不是真正的記憶體複製,而只是建立了乙個指標,因而大大提高效率。但這不是一直成立的,如果在複製新物件之後,大部www.cppcns.com分物件都還需要繼續進行寫操作會產生大量的分頁錯誤,得不償失。所以cow高效的情況只是在複製新物件之後,在一小部分的記憶體分頁上進行寫操作。
在php 核心中同樣使用了寫時複製機制來避免在賦值時導致記憶體增加,比如我們在使用foreach迴圈體時,可以發現其中的奧秘,示例**:
複製** **如下:
$m1 = memory_get_usage();
$str= aaaaaaaaaaaaaa eof; $arr = explode("\n", $str); $count=0; foreach($arr as $v) $m2 = memory_get_usage(); echo $m2-$m1; 當我們執行此代程式設計客棧碼時會得到記憶體占用為:788 複製** **如下: $m1 = memory_get_usage(); $str= aaaaaaaaaaaaaa程式設計客棧 eofuiwalyiop; $arr = explode("\n", $str); $count=0; foreach($arr as $v) $m2 = memory_get_usage(); echo $m2-$m1; 當我們取消 //$v='aaaaaaaaaaaaaa'; 的注釋,此時記憶體占用數值為:840,注意記憶體增長了。 複製** **如下: $m1 = memory_get_usage(); $str= aaaaaaaaaaaaaa eof; $arr = explode("\n", $str); $count=0; foreach($arr as &$v) $m2 = memory_get_usage(); echo $m2-$m1; 當我們將foreach中的$v 改寫為 &$v 時,不管是否注釋迴圈體中對$v的注釋,我們都可以得到記憶體占用為:788 這裡就說明了cow機制的介入,當我們在foreach迴圈中純粹的只用到對$v 的讀操作時,php核心會將$v這個變數的記憶體位址指向到$arr中陣列這一索引的記憶體位址,並沒有將陣列中的資料複製乙份給到變數$v,此時記憶體占用情況和使用&$v 是一樣的。但當我們在迴圈體內對$v進行寫操作時,寫時複製機制就被啟用了,此時php會重新開闢一段記憶體空間給到$v變數,而將原先$v指向陣列的記憶體位址給斷開了,此時記憶體必然就會增長了。 這裡可以得出另外乙個結論:當我們在讀取大資料的時候,要注意cow機制引入的記憶體增長影響,同樣避免不必要的對變數寫,可以提高**執行效能。 本文標題: php中copy on write寫時複製機制介紹 本文位址: 從乙個例子說起 foo 1 bar foo echo foo bar 變數 foo 賦值給變數 bar,這兩個變數具有相同的值,沒有必要新申請記憶體空間,他們可以共享同一塊記憶體。在很多場景下php 的 cow 對記憶體進行優化。比如 變數的多次賦值 函式引數傳遞,並在函式體內修改實參等。這是一段摘... 什麼是copyonwrite容器 copyonwrite容器即寫時複製的容器。通俗的理解是當我們往乙個容器新增元素的時候,不直接往當前容器新增,而是先將當前容器進行copy,複製出乙個新的容器,然後新的容器裡新增元素,新增完元素之後,再將原容器的引用指向新的容器。這樣做的好處是我們可以對copyon... 剛了解到。趕快記下來。每個程式都有自己的資料段,段。補充 dll有自己的資料段,但沒有自己的堆疊。乙個dll,被很多程式呼叫,為什麼 段共享,資料段不共享?就是因為 記憶體的copy on write 機制 程式1呼叫這個dll,執行過程中,dll的資料段肯定會改變,那記憶體就會被copy乙份,原來...PHP寫時複製(Copy On Write)
CopyOnWrite容器理解
記憶體的COPY ON WRITE機制