摘要:變量的分離和引用今天看了一下鳥哥博客變量的分離和引用的內(nèi)容就做了一個(gè)筆記如果我們我們創(chuàng)建一個(gè)變量就分配一次內(nèi)存那么像上邊的代碼那么就會(huì)造成內(nèi)存的極大浪費(fèi)中的變量是一個(gè)指向的符號(hào)那么我們就可以在中來優(yōu)化上邊的代碼的中有一個(gè)字段用來記錄當(dāng)前被引
PHP 變量的分離和引用
今天看了一下鳥哥博客變量的分離和引用的內(nèi)容, 就做了一個(gè)筆記!
$var = "I have a dream"; $var2 = $var; $var3 = $var;
如果我們我們創(chuàng)建一個(gè)變量就分配一次內(nèi)存, 那么像上邊的代碼,那么就會(huì)造成內(nèi)存的極大浪費(fèi). php中的變量是一個(gè)指向zval的符號(hào), 那么我們就可以在zval中來優(yōu)化上邊的代碼!
php的zval中有一個(gè)recount字段, 用來記錄當(dāng)前zval被引用的次數(shù)
$var = "abc"; //refcount = 1 $varCopy = $var; //refcount = 2
創(chuàng)建第一個(gè)變量$var時(shí)refcount的值為1, 當(dāng)創(chuàng)建第二個(gè)變量$varCopy時(shí), refcount的值為2.我們?cè)趺茨懿榭吹竭@個(gè)值呢, 可以通過php提供的debug_zval_dump輸出變量的內(nèi)容和refcount
$var = "abc"; //refcount = 1 debug_zval_dump($var); //string(3) "abc" refcount(2) $varCopy = $var; //refcount = 2 debug_zval_dump($var); //string(3) "abc" refcount(3)
為什么打印的結(jié)果和我們預(yù)想的結(jié)果不一致呢, 函數(shù)debug_zval_dump有一個(gè)值傳遞的形參, 就相當(dāng)于又執(zhí)行了一次$arg = $var, 執(zhí)行這段代碼的時(shí)候$var的refcount又增加了1,所以在debug_zval_dump內(nèi)部打印的結(jié)果就比實(shí)際的要大1.如果我們對(duì)一個(gè)變量進(jìn)行unset那么會(huì)是一種什么樣的效果呢
$var = "abc"; $varCopy = $var; unset($var); debug_zval_dump($varCopy); //string(3) "abc" refcount(2)
如果像下邊這段代碼會(huì)發(fā)生什么呢:
$var = "abc"; $varCopy = $var; $var = 1;
如果一個(gè)變量被重新賦值, 在賦值的過程中會(huì)首先檢測(cè)refcount的值, 如果refcount大于1, php就會(huì)執(zhí)行一個(gè)分離過程.上邊的代碼在執(zhí)行到第三行的時(shí)候, php發(fā)現(xiàn)$var指向的zval的refcount大于1, 那么php就會(huì)復(fù)制一個(gè)新的zval出來, 將原來的zval的refcount減1,并修改變量符號(hào)表, 是$var指向新的zval結(jié)構(gòu) 1.這樣原來的$var和$varCopy就各自指向了不同的結(jié)構(gòu). 這個(gè)就是
copy one write 也叫寫時(shí)復(fù)制
如果我們?cè)偌由弦玫那闆r, 那么整個(gè)過程就會(huì)更加復(fù)雜!
$var = "abc"; $varRef = &$var; $varRef = 1;
最終$var的結(jié)果是1, 這個(gè)過程被稱為
change on write 寫時(shí)改變
這次的復(fù)制是不需要進(jìn)行變量分離的,需要用到zval的is_ref字段, 對(duì)于上邊的代碼, 當(dāng)?shù)诙袌?zhí)行以后, $var所代表的zval的refcount變?yōu)?, 同時(shí)設(shè)置is_ref為1.
第三行的時(shí)候, php會(huì)首先檢查$varRef的zval的is_ref字段,如果為1, 則不分離.
$var = "abc"; $varCopy = $var; $varRef = &$var;
上邊的情況, 存在copy on write 同時(shí)也有change on write, 是怎么運(yùn)作的呢.
當(dāng)執(zhí)行第二行的時(shí)候和前邊的copy on write一樣, $var和$varCopy指向相同的zval,refcount為2
當(dāng)執(zhí)行第三行的時(shí)候, php發(fā)現(xiàn)要操作的zval($var所指向的zval)的refcount大于1, php就會(huì)執(zhí)行分離操作, 把$varCopy分離出去, 并將$var和$varRef做change on write關(guān)聯(lián), 也就是refcount=2, is_ref=1
如果整個(gè)過程反過來2
$var = "abc"; //refcount=1, is_ref=0 $varRef = &$var; //refcount=2, is_ref=1 $varCopy = $var; //refcont=1, is_ref=0
第三行代碼, 因?yàn)樯线叺淖兞?b>$var對(duì)應(yīng)的zval有is_ref的存在, 那么當(dāng)前的變量就會(huì)直接復(fù)制一份出來, 而不會(huì)觸發(fā)copy on write機(jī)制.
我們?cè)诳匆欢未a
$var = "abc"; $varRef = &$var; debug_zval_dump($var); //string(3) "abc" refcount(1)
這個(gè)結(jié)果和預(yù)想的又有所差別, 是什么原因的? debug_zval_dump() 需要一個(gè)值傳遞的形參, 那么執(zhí)行debug_zval_dump($var)的時(shí)候就相當(dāng)于debug_zval_dump($arg = $var) 這樣就會(huì)造成變量的分離,在debug_zval_dump($arg)就相當(dāng)于對(duì)一個(gè)全新的變量執(zhí)行!
這個(gè)地方按我的理解應(yīng)該是要全新生成一個(gè)zval, 然后修改原來的zval的refcount ?
這個(gè)是我自己猜想的, 不知道是否正確.請(qǐng)輸入代碼 ?
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/21216.html
摘要:引用計(jì)數(shù)變量分離寫時(shí)拷貝我們一步步來理解語言特性是腳本語言,所謂腳本語言,就是說并不是獨(dú)立運(yùn)行的,要運(yùn)行代碼需要解析器,用戶編寫的代碼最終都會(huì)被解析器解析執(zhí)行的執(zhí)行是通過引擎,是用編寫的用戶編寫的代碼最終都會(huì)被翻譯成的虛擬機(jī)的虛擬指令來執(zhí)行 zval、引用計(jì)數(shù)、變量分離、寫時(shí)拷貝我們一步步來理解1、php語言特性PHP是腳本語言,所謂腳本語言,就是說PHP并不是獨(dú)立運(yùn)行的,要運(yùn)行PHP...
摘要:體現(xiàn)了業(yè)務(wù)與顯示的分離,盡量分離。就負(fù)責(zé)判斷條件,并取出數(shù)據(jù)來。顯示的工作盡量靠前頁面緩存緩存,重要概念。減輕了數(shù)據(jù)庫的壓力。控制局部不緩存在標(biāo)簽中控制,該標(biāo)簽不緩存。模板調(diào)用特殊方法使用對(duì)象注冊(cè)的方式來解決。文件命名函數(shù)名定 模板 數(shù)據(jù)與表現(xiàn)層的標(biāo)簽分離 smarty是PHP 與 HTML代碼的分離 小型模板類 $smarty 的工作流程: 把需要顯示的全局變量,賦值塞到對(duì)象內(nèi)部的...
摘要:執(zhí)行原理是一門應(yīng)用非常簡(jiǎn)單,開發(fā)效率極高的一門語言,其弱類型的變量能省去程序員大量的定義變量類型轉(zhuǎn)換等的時(shí)間和精力。程序最終被翻譯為一組處理函數(shù)的順序執(zhí)行。只有減為時(shí)才會(huì)真正執(zhí)行銷毀操作。 PHP執(zhí)行原理 php是一門應(yīng)用非常簡(jiǎn)單,開發(fā)效率極高的一門語言,其弱類型的變量能省去程序員大量的定義變量、類型轉(zhuǎn)換等的時(shí)間和精力。它是一種適用于web開發(fā)的動(dòng)態(tài)語言。 1. php設(shè)計(jì)的原理和特點(diǎn)...
摘要:在中算法,當(dāng)節(jié)點(diǎn)緩沖區(qū)滿了之后,垃圾分析算法就會(huì)啟動(dòng),并且會(huì)釋放掉發(fā)現(xiàn)的垃圾,從而回收內(nèi)存。在編程中程序員不需要手動(dòng)處理內(nèi)存資源分配與釋放,意味著本身實(shí)現(xiàn)了垃圾回收處理機(jī)制。 PHP是一種弱類型的腳本語言,弱類型不表示PHP變量沒有類型的區(qū)別,PHP變量有8種原始類型:四種標(biāo)量類型: boolean(布爾值) integer(整型) float(浮點(diǎn)型) 兩種復(fù)合類型: arra...
摘要:支持字符串哈希列表集合有序集合等數(shù)據(jù)結(jié)構(gòu),目前不支持事務(wù)。是多入口以下關(guān)于表驅(qū)動(dòng)法的描述,錯(cuò)誤的是表驅(qū)動(dòng)法可以作為復(fù)雜繼承結(jié)構(gòu)的替代方案,難點(diǎn)在于一個(gè)經(jīng)過深思熟慮的查詢表。表驅(qū)動(dòng)法查找無規(guī)則分布的數(shù)據(jù)采用階梯訪問的方法最佳。 1、有關(guān)PHP字符串的說法,不對(duì)的是: CA、如果一個(gè)腳本的編碼是ISO-8859-1,則其中的字符串也會(huì)被編碼為 ISO-8859-1。B、PHP的字符串在內(nèi)部...
閱讀 3045·2021-09-22 14:59
閱讀 1878·2021-09-22 10:02
閱讀 2115·2021-09-04 16:48
閱讀 2265·2019-08-30 15:53
閱讀 2971·2019-08-30 11:27
閱讀 3410·2019-08-29 18:35
閱讀 966·2019-08-29 17:07
閱讀 2676·2019-08-29 13:27