日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

分析PHP的垃圾回收機制

瀏覽:20日期:2022-09-07 08:35:01

如果用過C語言,那么申請內存的方式是malloc或者是calloc,然后你用完這個內存后,一定不要忘了用free函數去釋放掉,這就是傳說中手動垃圾回收,一般都是掃地神僧用這種方式。很多高層次語言中,你這輩子都是接觸不到內存管理的,比如世界上最好的語言php,這種語言替你管理了內存,你就安安心心寫爛代碼即可。寫php的,你說你關心內存,我是不怎么相信的,一定是你在裝逼。當然了,如果你用的swoole或者wm或者自己發明的常駐內存級php應用,那你將不得不關注內存泄露問題,也就說一定要記得釋放無用變量。那么,在用的最普遍地最傳統的web開發中,php的自動垃圾回收機制是怎樣的呢?這個問題我們先這么想,就是都知道php是C語言實現的,現在把C語言給你放在這里了,然后你想想如何用C語言實現對一個變量的統計以及釋放。你不要想如何實現php,你就想C語言如何實現一個變量,從聲明開始到最后沒人用了,就把這個變量所占的內存給釋放掉。你從這個角度出發,就會舒服一些,這不再是一個技術難題,而是一個傻逼產品經理提的一個傻逼需求。好了,步入正題,PHP進行內存管理的核心算法一共兩項:一是引用計數,二是寫時拷貝,請理(bei)解(song)。當你聲明一個PHP變量的時候,C語言就在底層給你搞了一個叫做zval的struct(結構體);如果你還給這個變量賦值了,比如“hello world”,那么C語言就在底層再給你搞一個叫做zend_value的union(聯合體),總體看來就是這樣的:

好了,進入代碼實戰階段,注意兩點:

$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’);

輸出的結果是:

分析PHP的垃圾回收機制

其中,zval struct結構體用于保存$a,zend_value union聯合體用于保存數據內容也就是’hello916’。由于后面又聲明了b和c,所以C不得不又在底層給你搞出兩個zval struct結構體來。

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

zval {

string 'a' //變量的名字是a

value zend_value //變量的值

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

}

zend_value {

string 'hello916' //值的內容

refcount 1 //引用計數

}

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

這個refcount就是傳說中的引用計數了,初始化的時候a后面的引用次數為1(注意,正確說法應該是a后面的賦值的數組zend_value引用計數為1,而不是a這個變量zval本身)。然后我們將$b = $a,其實相當于又一個變量指向了這個zend_value,所以refcount變為2,最后將$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;

// 運行結果,不用我說吧,腳趾頭都知道是’hello’.mt_rand( 1, 1000 )的結果,絕對不可能是123。

其實,當你把$a賦值給$b的時候,$a的值并沒有真的復制了一份,這樣是對內存的極度不尊重,也是對時間復雜度的極度不尊重,計算機僅僅是將$b指向了$a的值而已,這就叫多快好省。那么,什么時候真正的發生復制呢?就是當我們修改$a的值為123的時候,這個時候就不得已進行復制,避免$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’);

// 運行結果為1,其中的原理你自己應該能理順了昂

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

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

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

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

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

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

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

以上就是淺談PHP的垃圾回收機制的詳細內容,更多關于PHP的垃圾回收機制的資料請關注好吧啦網其它相關文章!

標簽: PHP
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
91成人精品视频| 亚洲网址在线观看| 亚洲精品免费观看| 中文字幕日本一区| 视频在线观看一区二区三区| 在线观看免费一区二区| 亚洲手机视频| 在线亚洲一区| 午夜电影一区| 综合一区av| 国产欧美高清视频在线| 国产精品第一| 欧美三级精品| 99亚洲视频| 国产精品亚洲欧美日韩一区在线| 麻豆国产91在线播放| 色婷婷色综合| 久久xxxx精品视频| 国产欧美一区二区色老头| 久久精品国产网站| 91精品久久久久久久久久不卡| 国产精品av一区二区| 亚洲精品九九| 国产精品久久久久久久久久10秀 | 国产欧美高清| 欧美性感美女一区二区| 亚洲久久一区| 九色porny丨国产首页在线| 99久久婷婷| 欧美一区二区三区久久精品| 久久青草久久| 国产图片一区| 精品91久久久久| 久久影院资源站| 爽爽淫人综合网网站| 国内揄拍国内精品久久| 亚洲精品一区二区在线看| 国产欧美一区二区三区精品观看| 999久久久精品国产| 国产精品多人| 欧美亚洲网站| 首页亚洲欧美制服丝腿| 久久精品国产亚洲夜色av网站| 久久国产三级精品| 免费观看在线综合| 99久久精品网| 韩国精品主播一区二区在线观看 | 欧美a在线观看| 综合国产在线| 播放一区二区| 精品一区二区三区中文字幕视频| 亚洲精品在线国产| 亚洲日本在线观看视频| 国产毛片久久| 亚洲激情精品| 亚洲精品极品少妇16p| 久久一级电影| 久久天堂精品| 日韩在线视频精品| 色综合五月天| 综合日韩av| 日韩一区二区三区在线免费观看| sm捆绑调教国产免费网站在线观看| 国产精品啊啊啊| 日韩成人一级| 国产欧美丝祙| 国产成人久久| 日韩视频网站在线观看| 婷婷综合六月| 欧美日韩国产在线观看网站| 亚洲高清毛片| 免费在线观看视频一区| 亚洲69av| 免费看一区二区三区| 9999国产精品| 五月综合激情| 亚洲精品在线a| 蜜桃久久久久| 99久久99久久精品国产片果冰| 免费福利视频一区二区三区| 国产国产精品| 久久国际精品| 久久国产中文字幕| 亚洲狼人精品一区二区三区| 国产麻豆一区二区三区| 国产成人在线中文字幕| 中日韩男男gay无套| 欧美永久精品| se01亚洲视频| 日韩中文字幕一区二区高清99| 免费在线观看一区| 在线亚洲观看| 国产成人精品亚洲线观看| 激情丁香综合| 综合欧美精品| 岛国av在线网站| 免费看欧美美女黄的网站| 精品亚洲精品| 日韩一区二区三区在线看| 成人国产精品一区二区免费麻豆| 亚洲精品1区| 日韩成人a**站| 日韩国产欧美视频| 樱桃成人精品视频在线播放| 开心激情综合| 四虎在线精品| 日韩视频久久| 人人草在线视频| 国产精品男女| 欧美日韩精品一本二本三本 | 国产资源在线观看入口av| 日韩一二三区在线观看| 99久久精品国产亚洲精品| 久久久久九九精品影院| 久久国产高清| 91精品久久久久久久久久不卡| 老司机精品在线| 国产精品4hu.www| 日韩av一区二区在线影视| 日韩视频免费| 99视频精品| 亚洲欧洲美洲av| 免费一区二区三区在线视频| 日韩激情中文字幕| 日韩专区视频网站| 婷婷视频一区二区三区| 天使萌一区二区三区免费观看| 欧美/亚洲一区| 99亚洲视频| 夜夜嗨av一区二区三区网站四季av| 免费av一区| 国产精品腿扒开做爽爽爽挤奶网站| 亚洲精品一区二区在线看| 婷婷久久一区| 日韩精品一级中文字幕精品视频免费观看 | 粉嫩av一区二区三区四区五区 | 男人的天堂久久精品| 丝袜脚交一区二区| 亚州精品视频| 国产精品欧美一区二区三区不卡| 国产伦精品一区二区三区在线播放| 国产欧美一区二区色老头| 久久中文精品| 日韩成人高清| 尤物在线精品| 国产日韩一区二区三区在线| 久久香蕉网站| 高潮一区二区| 综合激情网站| 日产精品一区二区| 91精品99| 91精品国产经典在线观看| 精品国产一区二区三区2021| 视频福利一区| 亚洲精品高潮| 国产高清不卡| 日韩激情中文字幕| 欧美日韩在线观看视频小说| 亚洲精品伦理| 欧美久久天堂| 欧美三区不卡| 九色精品91| 日韩国产精品久久久| 久久久精品五月天| 久久国内精品| 日韩精品一区第一页| sm久久捆绑调教精品一区| 日韩精品久久久久久| 久久在线免费| 国产专区精品| 日韩不卡在线观看日韩不卡视频| 久久久久99| 成人污污视频| 国产精品成人国产| 一区二区三区国产盗摄| 婷婷综合亚洲| 午夜欧美巨大性欧美巨大| 日本麻豆一区二区三区视频| 99久久精品费精品国产| 福利在线免费视频| 国产精品一区二区av日韩在线| 中文国产一区| 91超碰国产精品| 99久久亚洲精品蜜臀| 91一区二区三区四区| 免费亚洲一区| 美女视频黄 久久| 欧美欧美黄在线二区| 亚洲精品乱码| 婷婷亚洲成人| 日本久久一区| 日韩高清在线不卡| 在线一区免费| 91成人超碰| 一区二区三区四区日韩| 亚洲精品在线二区| 日本成人手机在线| 久久国产人妖系列| 欧美国产专区| 精品视频网站|