PHP中寫(xiě)時(shí)復(fù)制機(jī)制的示例分析-創(chuàng)新互聯(lián)

小編給大家分享一下PHP中寫(xiě)時(shí)復(fù)制機(jī)制的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)新互聯(lián)建站制作網(wǎng)站網(wǎng)頁(yè)找三站合一網(wǎng)站制作公司,專注于網(wǎng)頁(yè)設(shè)計(jì),成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作,網(wǎng)站設(shè)計(jì),企業(yè)網(wǎng)站搭建,網(wǎng)站開(kāi)發(fā),建網(wǎng)站業(yè)務(wù),680元做網(wǎng)站,已為上千服務(wù),創(chuàng)新互聯(lián)建站網(wǎng)站建設(shè)將一如既往的為我們的客戶提供最優(yōu)質(zhì)的網(wǎng)站建設(shè)、網(wǎng)絡(luò)營(yíng)銷推廣服務(wù)!

什么是寫(xiě)時(shí)復(fù)制(Copy On Write)?

答:在復(fù)制一個(gè)對(duì)象的時(shí)候并不是真正的把原先的對(duì)象復(fù)制到內(nèi)存的另外一個(gè)位置上,而是在新對(duì)象的內(nèi)存映射表中設(shè)置一個(gè)指針,指向源對(duì)象的位置,并把那塊內(nèi)存的Copy-On-Write位設(shè)置為1.這樣,在對(duì)新的對(duì)象執(zhí)行讀操作的時(shí)候,內(nèi)存數(shù)據(jù)不發(fā)生任何變動(dòng),直接執(zhí)行讀操作;而在對(duì)新的對(duì)象執(zhí)行寫(xiě)操作時(shí),將真正的對(duì)象復(fù)制到新的內(nèi)存地址中,并修改新對(duì)象的內(nèi)存映射表指向這個(gè)新的位置,并在新的內(nèi)存位置上執(zhí)行寫(xiě)操作。

這個(gè)技術(shù)需要跟虛擬內(nèi)存和分頁(yè)同時(shí)使用,好處就是在執(zhí)行復(fù)制操作時(shí)因?yàn)椴皇钦嬲膬?nèi)存復(fù)制,而只是建立了一個(gè)指針,因而大大提高效率。但這不是一直成立的,如果在復(fù)制新對(duì)象之后,大部分對(duì)象都還需要繼續(xù)進(jìn)行寫(xiě)操作會(huì)產(chǎn)生大量的分頁(yè)錯(cuò)誤,得不償失。所以COW高效的情況只是在復(fù)制新對(duì)象之后,在一小部分的內(nèi)存分頁(yè)上進(jìn)行寫(xiě)操作。

在PHP 內(nèi)核中同樣使用了寫(xiě)時(shí)復(fù)制機(jī)制來(lái)避免在賦值時(shí)導(dǎo)致內(nèi)存增加,比如我們?cè)谑褂胒oreach循環(huán)體時(shí),可以發(fā)現(xiàn)其中的奧秘,示例代碼:

$m1 = memory_get_usage();
$str=<<<EOF
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
EOF;
$arr = explode("\n", $str);
$count=0;
foreach($arr as $v){
    $count++;
    //$v='aaaaaaaaaaaaaa';
}
$m2 = memory_get_usage();
echo $m2-$m1;


當(dāng)我們執(zhí)行此代碼時(shí)會(huì)得到內(nèi)存占用為:788

復(fù)制代碼 代碼如下:

$m1 = memory_get_usage();
$str=<<<EOF
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
EOF;
$arr = explode("\n", $str);
$count=0;
foreach($arr as $v){
$count++;
$v='aaaaaaaaaaaaaa';
}
$m2 = memory_get_usage();
echo $m2-$m1;


當(dāng)我們?nèi)∠?//$v='aaaaaaaaaaaaaa';  的注釋,此時(shí)內(nèi)存占用數(shù)值為:840,注意內(nèi)存增長(zhǎng)了。

復(fù)制代碼 代碼如下:

$m1 = memory_get_usage();
$str=<<<EOF
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
EOF;
$arr = explode("\n", $str);
$count=0;
foreach($arr as &$v){
$count++;
//$v='aaaaaaaaaaaaaa';
}
$m2 = memory_get_usage();
echo $m2-$m1;


當(dāng)我們將foreach中的$v 改寫(xiě)為 &$v 時(shí),不管是否注釋循環(huán)體中對(duì)$v的注釋,我們都可以得到內(nèi)存占用為:788

這里就說(shuō)明了COW機(jī)制的介入,當(dāng)我們?cè)趂oreach循環(huán)中純粹的只用到對(duì)$v 的讀操作時(shí),PHP內(nèi)核會(huì)將$v這個(gè)變量的內(nèi)存地址指向到$arr中數(shù)組這一索引的內(nèi)存地址,并沒(méi)有將數(shù)組中的數(shù)據(jù)復(fù)制一份給到變量$v,此時(shí)內(nèi)存占用情況和使用&$v 是一樣的。但當(dāng)我們?cè)谘h(huán)體內(nèi)對(duì)$v進(jìn)行寫(xiě)操作時(shí),寫(xiě)時(shí)復(fù)制機(jī)制就被激活了,此時(shí)PHP會(huì)重新開(kāi)辟一段內(nèi)存空間給到$v變量,而將原先$v指向數(shù)組的內(nèi)存地址給斷開(kāi)了,此時(shí)內(nèi)存必然就會(huì)增長(zhǎng)了。

這里可以得出另外一個(gè)結(jié)論:當(dāng)我們?cè)谧x取大數(shù)據(jù)的時(shí)候,要注意COW機(jī)制引入的內(nèi)存增長(zhǎng)影響,同樣避免不必要的對(duì)變量寫(xiě),可以提高代碼運(yùn)行性能。

以上是“PHP中寫(xiě)時(shí)復(fù)制機(jī)制的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

本文標(biāo)題:PHP中寫(xiě)時(shí)復(fù)制機(jī)制的示例分析-創(chuàng)新互聯(lián)
本文URL:http://bm7419.com/article8/gdjop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、手機(jī)網(wǎng)站建設(shè)企業(yè)建站、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站建設(shè)網(wǎng)站設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)