摘要:在中算法,當(dāng)節(jié)點緩沖區(qū)滿了之后,垃圾分析算法就會啟動,并且會釋放掉發(fā)現(xiàn)的垃圾,從而回收內(nèi)存。在編程中程序員不需要手動處理內(nèi)存資源分配與釋放,意味著本身實現(xiàn)了垃圾回收處理機(jī)制。
PHP是一種弱類型的腳本語言,弱類型不表示PHP變量沒有類型的區(qū)別,PHP變量有8種原始類型:
四種標(biāo)量類型:
boolean(布爾值)
integer(整型)
float(浮點型)
兩種復(fù)合類型:
array(數(shù)組)
object(對象)
兩種特殊類型:
resource(資源)
NULL
在引擎內(nèi)部,變量都是用一個結(jié)構(gòu)體來表示的。這個結(jié)構(gòu)體可以在{PHPSRC}/Zend/zend.h中找到:
struct _zval_struct { /* Variable information */ zvalue_value value; /* value */ zend_uint refcount__gc; //代表一個計數(shù)器,表示有多少個變量名指向這個zval容器 zend_uchar type; /* active type */ zend_uchar is_ref__gc; //此字段是一個布爾值,用來標(biāo)識變量是否是一個引用,通過這個字段,PHP引擎可以區(qū)分一般變量和引用變量 };copy on write(寫時復(fù)制技術(shù))
父進(jìn)程fork子進(jìn)程之后,子進(jìn)程的地址空間還是簡單的指向父進(jìn)程的地址空間,只有當(dāng)子進(jìn)程需要寫地址空間中的內(nèi)容的時候,才會多帶帶分離一份給子進(jìn)程,這樣就算子進(jìn)程馬上調(diào)用exec函數(shù)也沒有關(guān)系,因為根本就不需要從父進(jìn)程的地址空間中拷貝內(nèi)容,這樣就節(jié)省了內(nèi)存同時又提高了速度。PHP5.3版本中對于新的GC算法(Concurrent Cycle Collection in Reference Counted Systems)這個邏輯可以敘述為:對一個一般變量a(isref=0)進(jìn)行一般的賦值操作,如果a所指向的zval的計數(shù)refcount大于1,那么需要為a重新分配一個新的zval,并且把之前的zval的計數(shù)refcount減少1。
幾個基本準(zhǔn)則:
如果一個zval的refcount增加,那么此zval還在使用,不屬于垃圾
如果一個zval的refcount減少到0,那么zval可以被釋放掉,不屬于垃圾
如果一個zval的refcount減少之后大于0,那么此zval還不能被釋放,此zval可能成為一個垃圾。
新的GC算法目的就是防止循環(huán)引用的變量引起內(nèi)存泄露問題。在PHP中GC算法,當(dāng)節(jié)點緩沖區(qū)滿了之后,垃圾分析算法就會啟動,并且會釋放掉發(fā)現(xiàn)的垃圾,從而回收內(nèi)存。
現(xiàn)在,如果我們試一下,將數(shù)組的引用賦值給數(shù)組中的一個元素,有意思的事情發(fā)生了:
這樣$a數(shù)組就有兩個元素,一個索引為0,值為字符one,另一個索引為1,為$a自身的引用,內(nèi)部存儲如下:
a: (refcount=2, is_ref=1)=array ( 0 => (refcount=1, is_ref=0)="one", 1 => (refcount=2, is_ref=1)=... )
“...”表示1指向a自身,是一個環(huán)形引用(循環(huán)引用):
這個時候我們對$a進(jìn)行unset,那么$a會從符號表中刪除,同時$a指向的zval的refcount減少1。
那么問題產(chǎn)生了,$a已經(jīng)不再符號表中了,用戶無法再訪問此變量,但是$a之前指向的zval的refcount變?yōu)?而不是0,因此不能被回收,這樣產(chǎn)生了內(nèi)存泄露:
這樣zval就成為一個垃圾了,新的GC要做的工作就是清理這種垃圾。
在PHP編程中程序員不需要手動處理內(nèi)存資源分配與釋放,意味著PHP本身實現(xiàn)了垃圾回收處理機(jī)制。PHP5.2中的垃圾回收算法---Reference Counting
這個算法叫做“引用計數(shù)”,其思想非常直觀和簡潔:為每個內(nèi)存對象分配一個計數(shù)器,當(dāng)一個內(nèi)存對象建立時計數(shù)器初始化為1(因此此時總是有一個變量引用此對象),以后每有一個新變量引用此內(nèi)存對象,則計數(shù)器加1,而每當(dāng)減少一個引用此內(nèi)存對象的變量則計數(shù)器減1,當(dāng)垃圾回收機(jī)制運作時,將所有計數(shù)器為0的內(nèi)存對象銷毀并回收其占用的內(nèi)存。而php中內(nèi)存對象就是zval,而計數(shù)器就是refcount__gc。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/28431.html
摘要:原文回收周期,增加一篇論文在底部。就是說,僅僅在引用計數(shù)減少到非零值時,才會產(chǎn)生垃圾周期。如果他們是循環(huán)引用周期的一部分,將永不能被清除進(jìn)而導(dǎo)致內(nèi)存泄漏。這個函數(shù)將返回使用這個算法回收的周期數(shù)。引用計數(shù)系統(tǒng)中的同步周期回收 原文:回收周期(Collecting Cycles) ,增加一篇論文在底部。 以下過程僅對數(shù)組和對象類型起作用。 傳統(tǒng)上,像以前的 php 用到的引用計數(shù)內(nèi)存機(jī)制,...
摘要:總結(jié)垃圾回收機(jī)制以的引用計數(shù)機(jī)制為基礎(chǔ)以前只有該機(jī)制同時使用根緩沖區(qū)機(jī)制,當(dāng)發(fā)現(xiàn)有存在循環(huán)引用的時,就會把其投入到根緩沖區(qū),當(dāng)根緩沖區(qū)達(dá)到配置文件中的指定數(shù)量后,就會進(jìn)行垃圾回收,以此解決循環(huán)引用導(dǎo)致的內(nèi)存泄漏問題開始引入該機(jī)制 php垃圾回收機(jī)制,對于PHPer來說是一個不陌生但是又不是很熟悉的內(nèi)容。那么php是怎么實現(xiàn)對不需要的內(nèi)存進(jìn)行回收的呢? php變量的內(nèi)部存儲結(jié)構(gòu) 首先還是...
摘要:所有這些類型,在內(nèi)部統(tǒng)一用一個叫做的結(jié)構(gòu)表示,在源代碼中這個結(jié)構(gòu)名稱為。的具體定義在源代碼的文件中,下面是相關(guān)代碼的摘錄。 【轉(zhuǎn)】淺談PHP5中垃圾回收算法(Garbage Collection)的演化 前言 PHP是一門托管型語言,在PHP編程中程序員不需要手工處理內(nèi)存資源的分配與釋放(使用C編寫PHP或Zend擴(kuò)展除外),這就意味著PHP本身實現(xiàn)了垃圾回收機(jī)制(Garbage C...
摘要:一概述集合是引入的新的內(nèi)置對象類型,其特點同數(shù)學(xué)意義的集合,即集合內(nèi)所有元素不重復(fù)元素唯一。數(shù)組集合對比數(shù)組和集合,數(shù)組可以加入重復(fù)數(shù)據(jù),而集合的所有元素是唯一的不允許重復(fù)。因此,適合臨時存放一組對象,以及存放跟對象綁定的信息。 本文同步帶你入門 帶你入門 JavaScript ES6 (五) 集合,轉(zhuǎn)載請注明出處。 前面我們學(xué)習(xí)了: for of 變量和擴(kuò)展語法 塊作用域變量和解構(gòu)...
摘要:后者的例子在給巨大的一個知名的組件庫的模板組件做單元測試時,就可能會出現(xiàn)問題。 PHP的垃圾回收機(jī)制 垃圾回收器,全稱Garbage Collection,簡稱GC,5.3版本之前 只是簡單判斷變量的zval的refcount是否為0,是的話就釋放,不是直至進(jìn)程結(jié)束(隱藏著變量內(nèi)存溢出的風(fēng)險). 如果你已經(jīng)安裝了? Xdebug,你能通過調(diào)用函數(shù) xdebug_debug_zval()...
閱讀 925·2023-04-25 19:49
閱讀 3958·2021-09-30 09:47
閱讀 2836·2021-09-13 10:21
閱讀 2764·2021-08-24 10:04
閱讀 3242·2019-08-30 15:55
閱讀 2464·2019-08-30 15:55
閱讀 2496·2019-08-30 15:54
閱讀 3532·2019-08-30 13:53