真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

PHP的垃圾回收機制相關(guān)知識點整理

本篇內(nèi)容主要講解“PHP的垃圾回收機制相關(guān)知識點整理”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“PHP的垃圾回收機制相關(guān)知識點整理”吧!

在臨朐等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站設(shè)計制作、網(wǎng)站設(shè)計 網(wǎng)站設(shè)計制作按需求定制設(shè)計,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),營銷型網(wǎng)站建設(shè),成都外貿(mào)網(wǎng)站制作,臨朐網(wǎng)站建設(shè)費用合理。

PHP目前的開發(fā)框架,除了主流常用的FPM框架,想必就是基于swoole拓展的常駐內(nèi)存開發(fā)了。

我們在FPM的開發(fā)模式中,每一次腳本程序結(jié)束之后,所有變量都會被銷毀,內(nèi)存會被釋放,所以我們不用太擔心。

但是常駐內(nèi)存開發(fā)模式就不一樣了,如果不注意變量內(nèi)存的使用,無法很好的管理內(nèi)存問題,會造成內(nèi)存泄露。

所以,我們一定要熟悉PHP的垃圾回收機制(Garbage Collector 簡稱GC) 

寫時復制與引用計數(shù)

寫時復制

在PHP7+版本中,有關(guān)于變量內(nèi)存的操作特性,采用了寫時復制,也就是說, 在必要的時候才會進行深拷貝(即發(fā)生寫的時候才會進行深拷貝).

當變量值為interned string字符串型(變量名,函數(shù)名,靜態(tài)字符串,類名等)時,變量值存儲在靜態(tài)區(qū),內(nèi)存回收被系統(tǒng)全局接管,引用計數(shù)將一直為1 。

當賦值變量的值為 整型,浮點型 時,php7底層將會直接把值存儲(php7的結(jié)構(gòu)體將會直接存儲簡單數(shù)據(jù)類型),refcount將為0,我們用代碼來看一下:

$a = 'chris'.time();$b = $a;  //此時$b指向$a的同一個內(nèi)存地址$c = $a;  //一樣xdebug_debug_zval('a');//a:(refcount=3, is_ref=0)string 'chris1614780053' (length=15)我們通過Xdebug來觀察變量的信息,他們指的都是同一個內(nèi)存地址,是引用。
$a = 'chris'.time();$b = '青玄';$c = $a;xdebug_debug_zval('a');xdebug_debug_zval('b');//a:(refcount=2, is_ref=0)string 'chris1614780283' (length=15)
 //b:(interned, is_ref=0)string '青玄' (length=6) //存在了靜態(tài)區(qū)我們通過Xdebug來觀察變量的信息,這時$b的值已經(jīng)發(fā)生了變化,這時候,才會使用新的內(nèi)存空間,$a的引用次數(shù)-1。

引用計數(shù)

每個php變量存在一個叫”zval”的變量容器中。一個zval變量容器,除了包含變量的類型和值,還包括兩個字節(jié)的額外信息。第一個是”is_ref”,是個bool值,用來標識這個變量是否是屬于引用集合(reference set)。通過這個字節(jié),php引擎才能把普通變量和引用變量區(qū)分開來,由于php允許用戶通過使用&來使用自定義引用,zval變量容器中還有一個內(nèi)部引用計數(shù)機制,來優(yōu)化內(nèi)存使用。第二個額外字節(jié)是”refcount”,用以表示指向這個zval變量容器的變量(也稱符號即symbol)個數(shù)。

官方文檔的描述

簡單來說,就是給變量引用的次數(shù)進行計算,當計數(shù)refcount不等于0時,說明這個變量已經(jīng)被引用,不能直接被回收,否則可以直接回收,用代碼來看看把

$a='chris'.time();$b=$a;$c=$a; $b='青玄';unset($c);xdebug_debug_zval('a');//a:(refcount=1, is_ref=0)string 'chris1614780526'(length=5)//我們可以看到,刪除$c,并不能把$a刪除,因為refcount=1

內(nèi)存泄漏

function a(){class A {
   public $ref;
   public $name;

   public function __construct($name) { $this->name = $name; echo($this->name.'->__construct();'.PHP_EOL);
   }

   public function __destruct() {  echo($this->name.'->__destruct();'.PHP_EOL);
   }}$a1 = new A('$a1');$a2 = new A('$a2');$a3 = new A('$3');$a1->ref = $a2;$a2->ref = $a1;unset($a1);unset($a2);echo('exit(1);'.PHP_EOL);}a();echo('exit(2);'.PHP_EOL);

當$a1和$a2的屬性互相引用時,unset($a1,$a2) 只能刪除變量的引用,卻沒有真正的刪除類的變量,這是為什么呢?

首先,類的實例化變量分為2個步驟

1:開辟類存儲空間,用于存儲類數(shù)據(jù)

2:實例化一個變量,類型為class,值指向類存儲空間

當給變量賦值成功后,類的引用計數(shù)為1,同時,a1->ref指向了a2,導致a2類引用計數(shù)增加1,同時a1類被a2->ref引用,a1引用計數(shù)增加1

當unset時,只會刪除類的變量引用,也就是-1,但是該類其實還存在了一次引用(類的互相引用),

這將造成這2個類內(nèi)存永遠無法釋放,直到被gc機制循環(huán)查找回收,或腳本終止回收(域結(jié)束無法回收).

PHP作用域的生命周期和變量回收

每個方法/函數(shù)都作為一個作用域,當運行完該作用域時,將會回收作用域內(nèi)的所有變量,全局變量只有在腳本結(jié)束后才會回收。

我們可以通過以下方式來手動回收:

  • unset() : unset的回收原理其實就是引用計數(shù)-1,當引用計數(shù)-1之后為0時,將會直接回收該變量,否則不做操作(這就是上面內(nèi)存泄漏的原因,引用計數(shù)-1并沒有等于0)。

  • 賦值為null :=null和unset($a),作用其實都為一致,null將變量值賦值為null,原先的變量值引用計數(shù)-1,而unset是將變量名從php底層變量表中清理,并將變量值引用計數(shù)-1,唯一的區(qū)別在于,=null,變量名還存在,而unset之后,該變量就沒了。

  • 變量覆蓋回收:通過給變量賦值其他值(例如null)進行回收,但是從程序的內(nèi)存占用來說,覆蓋變量并不是意義上的內(nèi)存回收,只是將變量的內(nèi)存修改為了其他值.內(nèi)存不會直接清空。

  • gc_collect_cycles :強制執(zhí)行周期回收,在PHP執(zhí)行中,一旦根緩沖區(qū)滿了或者調(diào)用gc_collect_cycles() 函數(shù)時,就會執(zhí)行垃圾回收

另外:為避免不得不檢查所有引用計數(shù)可能減少的垃圾周期,PHP會有算法把疑似垃圾的變量,放在根緩沖區(qū)(root buffer)中,在根緩沖區(qū)滿了的時候,也會對垃圾緩沖區(qū)進行一次回收。

到此,相信大家對“PHP的垃圾回收機制相關(guān)知識點整理”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!


網(wǎng)頁標題:PHP的垃圾回收機制相關(guān)知識點整理
新聞來源:http://weahome.cn/article/jjcpdo.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部