摘要:可以看到,該結構體存儲了關于變量值,有幾個變量指向該結構體,變量類型,是否為引用變量等信息。這個就是寫時復制,在作怪,他沒有在賦值的時候就分裂成兩個結構體,而是在我們改寫其中一個變量時發(fā)生效果,屬于一種慢復制也稱慢分裂。
想要走到技術的天花板,那么學習過程中在于知其然且知其所以然。
今天我們來討論一下PHP底層的寫時復制(也稱寫時分裂)。
首先我們先來看看一段代碼:
兩段代碼的輸出結果相信各位都知道,但是我們今天講講這之中發(fā)生了什么。
下圖是PHP存儲變量的結構體(為方便講解已寫了注釋),zend.h在Zend目錄下。
可以看到,該結構體存儲了關于變量值,有幾個變量指向該結構體,變量類型,是否為引用變量等信息。
那么第一次打印發(fā)生了什么呢?變量的信息進入了一個結構體,相關如下:
$name = ‘傍晚八點半’;
$myName = $name;
此時$name和$myName共用一個結構體的,refcount__gc為2,
我們發(fā)現(xiàn),$myName = $name;這個過程中并沒有主動變成兩個結構體(這也算PHP內(nèi)部實現(xiàn)優(yōu)化的一種,只用一個結構體,省了內(nèi)存)。
那么當代碼運行到 $myName = ‘gzchen’; 的時候,結構體如何變化呢?由于第一次輸出時是兩個變量共用結構體,那么此時更改其中一個變量,會不會導致兩個值一起變化呢?純粹從結構體的邏輯來看,是有可能的,畢竟大家共用著這個結構體嘛。
那么我們看下第二次打印是怎么樣的情況,相關變化如下:
并沒有按照我們所想的將$name和$myName同時改成’gzchen’,而是復制多了一份結構體出來,兩個結構體分別對應著$name和$myName。
這個就是寫時復制(Copy-on-write,COW)在作怪,他沒有在$myName = $name;賦值的時候就分裂成兩個結構體,而是在我們改寫其中一個變量時發(fā)生效果,屬于一種慢復制(也稱慢分裂)。
偽代碼如下:
我們再看下另外一段代碼:
輸出為’b’,中途發(fā)生了什么?
其實foreach遍歷過程中,并不是直接操作$arr(原數(shù)組)的,而是會將$arr復制出一個$arrcopy(實際上是一個副本,我這里以$arrcopy代替),foreach在遍歷過程中操作的其實一直是$arrcopy,大概的流程是這樣:
和上面舉得例子其實是一個道理,我們可以看出,剛開始($arr = $arrcopy)還是共用一個結構體的,但是$arr[$k] = $v又再次賦值,發(fā)生了寫時復制,結構體就分裂了。
然后前面說過foreach操作的是$arrcopy,所以$arr的結構體指針就被停留在第一位了(因為結構體不一樣了,$arrcopy沒辦法同步給$arr賦值了)。
其實這類技術通常只會在面試中用到,日常開發(fā)會用這種寫法的人終究還是少數(shù),暫時看不明白的朋友也不用太在意,只要知道有”寫時復制”這個情況出現(xiàn)就行了。
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/21525.html
摘要:前面寫過一篇底層分析關于寫時復制今天來講講關于強制分裂的知識,簡單來說,強制分裂就是在引用變量主動賦值前,該變量傳值賦值過,就會發(fā)生強制分裂。實際開發(fā)基本用不到這層原理,但在面試中強制分裂通常會和寫時復制一起考。 學習需要知其然而知其所以然,PHP底層相關就是這類知識。 前面寫過一篇《PHP底層分析:關于寫時復制(cow)》:https://segmentfault.com/a/119...
摘要:中基礎中的三大坑,遍歷,引用機制,數(shù)組。今天我們在講講中的一些奇怪現(xiàn)象。本文適合有一定基礎的。運行流程共用一個結構體開始遍歷數(shù)組,進行判斷,拷貝數(shù)組是一個新的結構體,操作的是新的結構體。那么遍歷數(shù)組時,全程與原數(shù)組無關。 PHP中基礎中的三大坑,foreach遍歷,引用機制&,數(shù)組。 今天我們在講講foreach中的一些奇怪現(xiàn)象。 在講解之前,可以先看看我其他相關的文章,屬于同一個大的...
摘要:只有在真正需要使用資源時才占用資源,寫時復制通常能減少資源的占用?;A方面規(guī)范新特性性能調(diào)優(yōu)垃圾回收機制安全攻擊原理和防范攻擊原理和防范注入攻擊防范密碼哈希計算機網(wǎng)絡協(xié)議協(xié)議連接過程 從一個例子說起: 很明顯在這段代碼執(zhí)行以后,$var_dup 的值應該還是laruence, 那么這又是怎么實現(xiàn)的呢?這就是 PHP 的 copy on write 機制: PHP 在修改一個變量以前,...
摘要:本文主要是針對,的話可以移步到慶哥的博客看,還有就是小菜我讀的是內(nèi)核剖析這本書。接下來我會使用到來調(diào)試源碼本文有參照博客中的部分內(nèi)容以及代碼。 前言 工作+實習快一年了,搞php后端開發(fā),一直很迷茫怎么提高自己,就先從php源碼開始吧,本人比較菜,本文章寫的比較趕時間,所以有什么錯誤或者漏掉的地方,望各位大神指正,多交流才能成長嘛,嘿嘿。本文主要是針對php7,php5的話可以移步到慶...
閱讀 3739·2021-11-24 09:39
閱讀 2686·2021-11-15 11:37
閱讀 2467·2021-11-11 16:55
閱讀 5968·2021-10-14 09:43
閱讀 3806·2021-10-08 10:05
閱讀 3109·2021-09-13 10:26
閱讀 2416·2021-09-08 09:35
閱讀 3608·2019-08-30 15:55