成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

php底層原理之變量(二)

bladefury / 3514人閱讀

摘要:但是對于結(jié)構(gòu)體中的和字段我們一直都沒有詳細(xì)介紹過,而這兩個字段其實(shí)是和變量之間賦值的原理有著密切的關(guān)系的。

上周我們從底層的角度介紹了php變量從生成->常量賦值->銷毀的完整生命周期(不了解的同學(xué)可以翻看一下前面的文章php底層原理之變量(一)),但是我們留了一個思考,不知道大家有答案了沒,變量之間的賦值在底層又是如何實(shí)現(xiàn)的呢?

變量之間賦值

php變量的zval結(jié)構(gòu),我們已經(jīng)介紹了很多遍了,這里我們就不再多作介紹了。但是對于zval結(jié)構(gòu)體中的refcount__gcis_ref__gc字段我們一直都沒有詳細(xì)介紹過,而這兩個字段其實(shí)是和變量之間賦值的原理有著密切的關(guān)系的。所以,我們這次從幾個例子入手,了解這兩個字段的變化和由此帶來的原理知識

寫時復(fù)制原理

舉例:

$a = "許錚的技術(shù)成長之路";
$b = $a;
xdebug_debug_zval("a", "b");

結(jié)果:

a: (refcount=2, is_ref=0)="許錚的技術(shù)成長之路"
b: (refcount=2, is_ref=0)="許錚的技術(shù)成長之路"

看到這里,大家可能會比較蒙。不是變量賦值了么?應(yīng)該發(fā)生值拷貝了呀?怎么兩個變量的引用計(jì)數(shù)不是1,而是2呢?

那是因?yàn)椋?strong>php在設(shè)計(jì)的時候,為了節(jié)省內(nèi)存,所以在變量之間賦值時,對于值相同的兩個變量,會共用一塊內(nèi)存,也就是會在全局符號表內(nèi)將變量b的變量指針指向變量a指向的同一個zval結(jié)構(gòu)體,而只有當(dāng)變量的zval結(jié)構(gòu)發(fā)生變化時,才會發(fā)生變量容器復(fù)制的內(nèi)存變化,也因此叫做寫時復(fù)制原理

那什么時候會發(fā)生寫時復(fù)制原理呢?

寫時復(fù)制原理觸發(fā)時機(jī):
php在修改一個變量時,如果發(fā)現(xiàn)變量的refcount>1,則會執(zhí)行變量容器的內(nèi)存復(fù)制

舉例:

$a = "許錚的技術(shù)成長之路";
$b = $a; //此時變量a和變量b共同指向同一個變量容器,即refcount>1
$b = "許錚的技術(shù)成長之路1" //觸發(fā)寫時復(fù)制機(jī)制
xdebug_debug_zval("a", "b");

結(jié)果:

a: (refcount=1, is_ref=0)="許錚的技術(shù)成長之路"
b: (refcount=1, is_ref=0)="許錚的技術(shù)成長之路1"
寫時改變原理

變量之間的賦值我們搞清楚了,那么變量和引用之間的賦值呢?我們還是通過舉例來說明

舉例:

$a = "許錚的技術(shù)成長之路";
$b = &$a;
xdebug_debug_zval("a", "b");

結(jié)果:

a: (refcount=2, is_ref=1)="許錚的技術(shù)成長之路"
b: (refcount=2, is_ref=1)="許錚的技術(shù)成長之路"

此時,我們發(fā)現(xiàn),變量a和b的refcount還是2,只不過is_ref變成了1,那是因?yàn)樵趯⒆兞縜引用賦值給變量b時,在原變量容器上作了修改,將is_ref變成了1,且refcount+1

那如果引用賦值的基礎(chǔ)上又發(fā)生了變量的改變了呢?

舉例:

$a = "許錚的技術(shù)成長之路";
$b = &$a;
$b = "許錚的技術(shù)成長之路1"
xdebug_debug_zval("a", "b");

結(jié)果:

a: (refcount=2, is_ref=1)="許錚的技術(shù)成長之路1"
b: (refcount=2, is_ref=1)="許錚的技術(shù)成長之路1"

是不是覺得很神奇?變量b和變量a的值一起發(fā)生改變了~其實(shí)這是因?yàn)橛|發(fā)了寫時改變原理

寫時改變原理觸發(fā)時機(jī):
is_ref為1的變量容器在被賦值之前,優(yōu)先檢查變量容器的is_ref是否等于1,如果為1,則不進(jìn)行寫時復(fù)制,而是在原變量容器基礎(chǔ)上作內(nèi)容修改;而如果將is_ref為1的變量容器賦值給其他變量時,則會立即觸發(fā)寫時復(fù)制

那么如果把剛剛舉得幾個例子合并在一起呢?最后結(jié)果又是什么呢?

舉例:

$a = "許錚的技術(shù)成長之路";
$b = $a; 
$c = &$a;
xdebug_debug_zval("a", "b", "c");

結(jié)果:

a: (refcount=2, is_ref=1)="許錚的技術(shù)成長之路"
b: (refcount=1, is_ref=0)="許錚的技術(shù)成長之路"
c: (refcount=2, is_ref=1)="許錚的技術(shù)成長之路"

整體執(zhí)行過程是這樣的,當(dāng)執(zhí)行到第二行時,變量容器的refcount會變成2,變量a和變量b共享同一個變量容器;當(dāng)執(zhí)行到第三行時,因?yàn)閷⒆兞縜的引用賦值給變量c,但是變量b和變量a已經(jīng)共享了同一個變量容器,此時變量容器如果要發(fā)生改變,因?yàn)閞efcount>2,所以會發(fā)生寫時復(fù)制,將變量a和變量b分離,之后將變量a引用賦值給變量c時,則會原基礎(chǔ)上進(jìn)行修改,is_ref變成1,且refcount變成2

思考

那么,下面的這個例子,最終結(jié)果是什么呢?歡迎大家在下方留言或私信我~

舉例:

$a = "許錚的技術(shù)成長之路";
$b = $a; 
$c = &$a;
$d = $a;
$e = "許錚的技術(shù)成長之路1"
$a = $e;
xdebug_debug_zval("a", "b", "c", "d", "e");

如果你喜歡我的文章,請點(diǎn)贊支持我下,并歡迎關(guān)注我的專欄,每周都會有原創(chuàng)且有深度的文章奉上喲~

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/31087.html

相關(guān)文章

  • php底層原理數(shù)組實(shí)現(xiàn)

    摘要:數(shù)組是最常用的數(shù)據(jù)類型,同時容易上手也得益于其強(qiáng)大的數(shù)組,但是數(shù)組在中是如何實(shí)現(xiàn)的呢首先,我們還是先了解下相關(guān)的數(shù)據(jù)結(jié)構(gòu),為下面的內(nèi)容打好基礎(chǔ)哈希表哈希表,顧名思義,即將不同的關(guān)鍵字映射到不同單元的一種數(shù)據(jù)結(jié)構(gòu)。 數(shù)組是PHPer最常用的數(shù)據(jù)類型,同時php容易上手也得益于其強(qiáng)大的數(shù)組,但是數(shù)組在php中是如何實(shí)現(xiàn)的呢? 首先,我們還是先了解下相關(guān)的數(shù)據(jù)結(jié)構(gòu),為下面的內(nèi)容打好基礎(chǔ) 哈希...

    HackerShell 評論0 收藏0
  • php底層原理變量(一)

    摘要:對于來說,變量有全局變量和局部變量之分那么,他們都是存儲到一個哈希表內(nèi)了么其實(shí)不是的,變量存儲也有作用域的概念。 上次跟大家講了垃圾回收機(jī)制后,有些小伙伴對底層原理比較感興趣,私信問我了一些關(guān)于變量的相關(guān)知識,既然大家對變量比較感興趣,那么這次我們來系統(tǒng)的講一下變量的底層原理 變量結(jié)構(gòu) 首先,我們還是先擺上我們的zval結(jié)構(gòu)體,即php所有變量都會以zval結(jié)構(gòu)體的形式實(shí)現(xiàn) struc...

    curlyCheng 評論0 收藏0
  • php底層原理垃圾回收機(jī)制

    摘要:總結(jié)垃圾回收機(jī)制以的引用計(jì)數(shù)機(jī)制為基礎(chǔ)以前只有該機(jī)制同時使用根緩沖區(qū)機(jī)制,當(dāng)發(fā)現(xiàn)有存在循環(huán)引用的時,就會把其投入到根緩沖區(qū),當(dāng)根緩沖區(qū)達(dá)到配置文件中的指定數(shù)量后,就會進(jìn)行垃圾回收,以此解決循環(huán)引用導(dǎo)致的內(nèi)存泄漏問題開始引入該機(jī)制 php垃圾回收機(jī)制,對于PHPer來說是一個不陌生但是又不是很熟悉的內(nèi)容。那么php是怎么實(shí)現(xiàn)對不需要的內(nèi)存進(jìn)行回收的呢? php變量的內(nèi)部存儲結(jié)構(gòu) 首先還是...

    light 評論0 收藏0
  • 人人都要知道的PHP底層運(yùn)行機(jī)制與工作原理?

    摘要:弱類型語言一個變量的類型并不是一開始就確定不變的,運(yùn)行中才會確定并可能發(fā)生隱式或顯示的類型轉(zhuǎn)換。引擎組件的模式降低內(nèi)部耦合。 一、PHP設(shè)計(jì)理念及特點(diǎn) 多進(jìn)程模型:由于PHP是多進(jìn)程模型,不同請求間互不干涉,這樣保證了一個請求掛掉不會對全盤服務(wù)造成影響,PHP也早支持多線程模型。弱類型語言:一個變量的類型并不是一開始就確定不變的,運(yùn)行中才會確定并可能發(fā)生隱式或顯示的類型轉(zhuǎn)換。引擎(Ze...

    ZHAO_ 評論0 收藏0
  • 如何"有計(jì)劃,高效率,優(yōu)簡歷"應(yīng)對面試

    摘要:雖然有了十全的計(jì)劃,但如何高效率去記住上面那么多東西是一個大問題,看看我是怎么做的。 前言 前一篇文章講述了我在三月份毫無準(zhǔn)備就去面試的后果,一開始心態(tài)真的爆炸,但是又不服氣,一想到每次回來后家人朋友問我面試結(jié)果的期待臉,越覺得必須付出的行動來證明自己了。 面經(jīng)傳送門:一個1年工作經(jīng)驗(yàn)的PHP程序員是如何被面試官虐的? 下面是我花費(fèi)兩個星期做的準(zhǔn)備,主要分三部分: 有計(jì)劃——計(jì)劃好...

    gyl_coder 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<