日韩一区,国产二区,欧美三区,日本大片在线看黄a∨免费,欧美人体做爰大胆视频,欧洲美女黑人粗性暴交视频,日,韩,欧美一区二区三区

首頁>文檔>技術(shù)文檔>PHP垃圾回收機制有什么作用?怎樣使用?

此組別內(nèi)的文章

需要支持?

如果通過文檔沒辦法解決您的問題,請?zhí)峤还潍@取我們的支持!

PHP垃圾回收機制有什么作用?怎樣使用?

這篇文章給大家分享的是PHP垃圾回收機制的內(nèi)容,一些朋友可能對于PHP垃圾回收機制不是很了解,本文會給大家來詳細(xì)的介紹一下PHP垃圾回收機制,希望能對大家學(xué)習(xí)或者工作有一定的幫助,感興趣的朋友接下來一起跟隨小編一起學(xué)習(xí)一下吧。

    PHP的垃圾回收機制

    垃圾回收機制是一種動態(tài)存儲分配的方案。它會自動釋放程序不再需要的已分配的內(nèi)存塊。垃圾回收機制可以讓程序員不必過分關(guān)心程序內(nèi)存分配,從而將更多的精力投入到業(yè)務(wù)邏輯。在現(xiàn)在的流行各種語言當(dāng)中,垃圾回收機制是新一代語言所共有的特征,如Python、PHP、C#、Ruby等都使用了垃圾回收機制。

    好了,進入代碼實戰(zhàn)階段,注意兩點:

$a = 'hello'. mt_rand( 1, 1000 ); 
echo xdebug_debug_zval( 'a');
$b = $a;
echo xdebug_debug_zval( 'a');
$c = $a;
echo xdebug_debug_zval( 'a');
unset( $c );
echo xdebug_debug_zval( 'a');

    輸出的結(jié)果是:

PHP垃圾回收機制有什么作用?怎樣使用?插圖

    其中,zval struct結(jié)構(gòu)體用于保存$a,zend_value union聯(lián)合體用于保存數(shù)據(jù)內(nèi)容也就是’hello916’。由于后面又聲明了b和c,所以C不得不又在底層給你搞出兩個zval struct結(jié)構(gòu)體來。

    其中,zval和zend value的結(jié)構(gòu)大概如下:(注意!?。∵@并不是完整正確的PHP zval和zend_value在C語言中struct和union實現(xiàn),僅僅是挑出最重點的部分寫出來,強調(diào)一下:你沒有必要一個字不差背誦過zval和zend_value,你只需要知道原理)

zval {

string “a” //變量的名字是a

value zend_value //變量的值

type string //變量是字符串類型

}

zend_value {

string “hello916” //值的內(nèi)容

refcount 1 //引用計數(shù)

}

    看到上面兩個,如果面試官問你php變量為什么能夠保存字符串”123″也能保存數(shù)字123,你知道該怎么回答了吧?就答出重點zval中有該變量的類型,當(dāng)是字符串123的時候,type就是string,此時value指向“123”;當(dāng)是整數(shù)123的時候,zval的type為int,value為123。這就是答題的思想,這很重要!而且,通過C語言都是可以實現(xiàn)的!具體真正的val和zend_value的模樣,有興趣的同學(xué)可以去網(wǎng)上搜搜,如果你沒有C語言的底子,可能比較吃力!前者是一個struct結(jié)構(gòu)體,后者是一個union聯(lián)合體!

    這個refcount就是傳說中的引用計數(shù)了,初始化的時候a后面的引用次數(shù)為1(注意,正確說法應(yīng)該是a后面的賦值的數(shù)組zend_value引用計數(shù)為1,而不是a這個變量zval本身)。然后我們將$b = $a,其實相當(dāng)于又一個變量指向了這個zend_value,所以refcount變?yōu)?,最后將$c = $a,同理,zend_value的refcount再次加1變成了3。然后,我們用unset( $c ),這會兒,C語言要做的就是把$c的zval給KO free掉,但是并不是free zend_value,這會兒zend_value的refcount就自然而然減1變成2了。

    那么寫時拷貝是什么意思呢?看下面代碼:

<?php
// 先不要問為什么非要加mt_rand,不然,絕筆說不過來了,到處都是坑
$a = 'hello'. mt_rand( 1, 1000 );
$b = $a;
$a = 123;
echo $b. PHP_EOL;
// 運行結(jié)果,不用我說吧,腳趾頭都知道是'hello'.mt_rand( 1, 1000 )的結(jié)果,絕對不可能是123。

    其實,當(dāng)你把$a賦值給$b的時候,$a的值并沒有真的復(fù)制了一份,這樣是對內(nèi)存的極度不尊重,也是對時間復(fù)雜度的極度不尊重,計算機僅僅是將$b指向了$a的值而已,這就叫多快好省。那么,什么時候真正的發(fā)生復(fù)制呢?就是當(dāng)我們修改$a的值為123的時候,這個時候就不得已進行復(fù)制,避免$b的值和$a的一樣。

<?php
$a = 'hello'. mt_rand( 1, 1000 );
$b = $a;
echo xdebug_debug_zval( 'a');
$a = 'world'. mt_rand( 2, 2000 );
echo xdebug_debug_zval( 'a');
// 運行結(jié)果為1,其中的原理你自己應(yīng)該能理順了昂

    叨逼叨了這么長,通過簡單的案例解釋清楚了兩個要點:引用計數(shù)和寫時拷貝,那么垃圾回收也該來了。當(dāng)一個zval在被unset的時候、或者從一個函數(shù)中運行完畢出來(就是局部變量)的時候等等很多地方,都會產(chǎn)生zval與zend_value發(fā)生斷開的行為,這個時候zend引擎需要檢測的就是zend_value的refcount是否為0,如果為0,則直接KO free空出內(nèi)容來。如果zend_value的recount不為0(廢話一定是大于0),這個value不能被釋放,但是也不代表這個zend_value是清白的,因為此zend_value依然可能是個垃圾。

    什么樣的情況會導(dǎo)致zend_value的refcount不為0,但是這個zend_value卻是個垃圾呢?PHP7種兩種情況:

<?php
$arr = [ 1 ];
$arr[] = &$arr;
unset( $arr );

    這種情況下,zend_value不會能釋放,但也不能放過它,不然一定會產(chǎn)生內(nèi)存泄漏,所以這會兒zend_value會被扔到一個叫做垃圾回收堆中,然后zend引擎會依次對垃圾回收堆中的這些zend_value進行二次檢測,檢測是不是由于上述兩種情況造成的refcount為1但是自身卻確實沒有人再用了,如果一旦確定是上述兩種情況造成的,那么就會將zend_value徹底抹掉釋放內(nèi)存。

    那么垃圾回收發(fā)生在什么時候?有些同學(xué)可能有疑問,就是php不是運行一次就銷毀了嗎,我要著gc有何用?并不是啦,首先當(dāng)一次fpm運行完畢后,最后一定還有g(shù)c的,這個銷毀就是gc;其次是,內(nèi)存都是即用即釋放的,而不是攢著非得到最后,你想想一個典型的場景,你的控制器里的某個方法里用了一個函數(shù),函數(shù)需要一個巨大的數(shù)組參數(shù),然后函數(shù)還需要修改這個巨大的數(shù)組參數(shù),你們應(yīng)該是函數(shù)的運行范圍里面修改這個數(shù)組,所以此時會發(fā)生寫時拷貝了,當(dāng)函數(shù)運行完畢后,就得趕緊釋放掉這塊兒內(nèi)存以供給其他進程使用,而不是非得等到本地fpm request徹底完成后才銷毀。

    說到最后,說些自己的話:大多數(shù)情況下,面試官問你問題主要是想一是要你個思維思路,二是看你學(xué)習(xí)程度。就像gc這個問題,其實很多腳本語言的垃圾回收機制基本上都是靠引用計數(shù)和寫時拷貝這兩種算法結(jié)合完成的,所以如果你設(shè)計一門腳本語言,gc機制就按照這兩種算法進行設(shè)計即可。其次是大多數(shù)phper不會看這些東西的,面試官問你這個問題不是要你死記硬背那么多細(xì)節(jié),你背不過的,他還是想探測你平時有沒有更積極地往深層發(fā)展的心態(tài)。

    注重體現(xiàn)重點,很多細(xì)節(jié)實在沒法寫,比如我舉個例子$a=[],xdebug_debug_zval( $a )的refcount值你猜是多少? 7.1.17下竟然是2,你是不是以為是1,然而并不是。不過你不用糾結(jié)這些細(xì)節(jié),gc的關(guān)鍵就是能說出引用計數(shù)的原理和寫時拷貝,很多細(xì)節(jié)深處都各種奇奇怪怪的東西,面試官自己都不一定知道。

    關(guān)于PHP垃圾回收機制的內(nèi)容就介紹到這,希望大家閱讀完這篇文章能有所收獲。最后,想要了解更多PHP垃圾回收機制的知識,大家可以關(guān)注其它的相關(guān)文章。

0 條回復(fù) A文章作者 M管理員
    暫無討論,說說你的看法吧
QQ客服
  • QQ176363189 點擊這里給我發(fā)消息
旺旺客服
  • 速度網(wǎng)絡(luò)服務(wù)商 點這里給我發(fā)消息
電子郵箱
  • sudu@yunjiasu.cc
微信客服
  • suduwangluo