摘要:垃圾回收所謂垃圾就是指通過循環(huán)引用自己引用自己,目前只在類型中有出現(xiàn)的形式而導(dǎo)致永遠(yuǎn)不為。當(dāng)出現(xiàn)垃圾之后,的引擎有對(duì)應(yīng)的垃圾回收機(jī)制。觸發(fā)這個(gè)機(jī)制的時(shí)機(jī)是每次出現(xiàn)減少時(shí)候。
自嘲)。。。。。2333,我覺得這是因?yàn)樵趐hp語言層面就幫我們解決了內(nèi)存回收的問題,但這讓我在和java大牛們吹牛逼的時(shí)候,聽到什么內(nèi)存泄露。。。。(納尼,我tmd怎么從來沒遇見過)一臉懵逼。
本人小菜,如果下面所寫有什么錯(cuò)誤的地方,請(qǐng)大神指出,并且下文,很多都是讀書+看源碼之后自己的總結(jié)。
前言在上一篇中我淺談的PHP中的基本數(shù)據(jù)容器,zend_value,zval
實(shí)際存儲(chǔ)數(shù)據(jù)的并不全是zend_value,還有一個(gè)被zend_value通過指針指向的具體的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)體,如_zend_array,_zend_string
struct _zend_string { zend_refcounted_h gc; zend_ulong h; /* hash value */ size_t len; char val[1]; };
struct _zend_array { zend_refcounted_h gc; union { struct { ZEND_ENDIAN_LOHI_4( zend_uchar flags, zend_uchar nApplyCount, zend_uchar nIteratorsCount, zend_uchar consistency) } v; uint32_t flags; } u; uint32_t nTableMask; Bucket *arData; uint32_t nNumUsed; uint32_t nNumOfElements; uint32_t nTableSize; uint32_t nInternalPointer; zend_long nNextFreeElement; dtor_func_t pDestructor; };
注意每個(gè)結(jié)構(gòu)體中都有一個(gè)名為gc的變量,這個(gè)變量其實(shí)就是 zend_refcounted_h 引用計(jì)數(shù)
內(nèi)存回收的兩種情況
正常的變量在生命周期完成之后的回收。
這種情況也就是說當(dāng)zend_value中refCount==0的時(shí)候,這時(shí)候?qū)儆谡5膬?nèi)存回收。
垃圾回收
所謂垃圾: 就是指通過循環(huán)引用(自己引用自己,目前只在array,object類型中有出現(xiàn))的形式而導(dǎo)致refcount永遠(yuǎn)不為0。這種情況下,如果不處理,但是這些內(nèi)存無法釋放,到時(shí)內(nèi)存泄露
代碼如下:
$a = array(1,2 ); xdebug_debug_zval("a"); $a[] = &$a; xdebug_debug_zval("a"); $b=$a; unset($a); xdebug_debug_zval("a"); xdebug_debug_zval("b");
結(jié)果如下
a: (refcount=1, is_ref=0) array (size=2) 0 => (refcount=0, is_ref=0)int 1 1 => (refcount=0, is_ref=0)int 2 a: (refcount=2, is_ref=1) array (size=3) 0 => (refcount=0, is_ref=0)int 1 1 => (refcount=0, is_ref=0)int 2 2 => (refcount=2, is_ref=1) &array< a: (refcount=0, is_ref=0)*uninitialized* b: (refcount=2, is_ref=0) array (size=3) 0 => (refcount=0, is_ref=0)int 1 1 => (refcount=0, is_ref=0)int 2 2 => (refcount=1, is_ref=1) &array<
按照正常邏輯,當(dāng)unset($a),之后,其對(duì)應(yīng)的zeng_value的refCount=1,is_ref=0,但是實(shí)際上它卻是等于refCount=2,is_ref=0, 這就導(dǎo)致,就算是unset($b),之后,refCount=1,is_ref=0,這種結(jié)果,像上面當(dāng)refCount=0后正常回收內(nèi)存。
![圖片上傳中...]
這就是 垃圾。
當(dāng)出現(xiàn)垃圾之后,php的zend引擎有對(duì)應(yīng)的垃圾回收機(jī)制。
其實(shí)這種機(jī)制的原理就是 :
(1).將這些垃圾放入buffer中。 (2).當(dāng)buffer到達(dá)一定數(shù)量之后,啟動(dòng)對(duì)所有垃圾的value自身的refCount-1,并將zend_refcounted中的gc_info變量置為GC_GRAY
typedef struct _zend_refcounted_h { uint32_t refcount; /* reference counter 32-bit */ union { struct { ZEND_ENDIAN_LOHI_3( zend_uchar type, zend_uchar flags, /* used for strings & objects */ uint16_t gc_info) /* 就是這個(gè)變量 keeps GC root number (or 0) and color */ } v uint32_t type_info; } u; } zend_refcounted_h;
(3).遍歷當(dāng)前buffer,當(dāng)refCount=0是則表示當(dāng)前的這個(gè)value的確是個(gè)垃圾,則將zend_refcounted中的gc_info變量置為GC_WHITE。然后因?yàn)樗械膙alue中都減1,所以再次遍歷,將那些減一后refcount !=0 的value+1,然后將zend_refcounted中的gc_info變量置為GC_BLACK (4).最后遍歷buffer,將buffer中的value的zend_refcounted中的gc_info為GC_WHITE刪除 講完GC垃圾回收算法的原理,貌似我還沒有講在什么時(shí)候會(huì)觸發(fā)將這個(gè)**可能**的垃圾放入buffer。。。。。。 ***觸發(fā)這個(gè)機(jī)制的時(shí)機(jī)是每次出現(xiàn)refCount減少時(shí)候。***
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/28469.html
摘要:所有這些類型,在內(nèi)部統(tǒng)一用一個(gè)叫做的結(jié)構(gòu)表示,在源代碼中這個(gè)結(jié)構(gòu)名稱為。的具體定義在源代碼的文件中,下面是相關(guān)代碼的摘錄。 【轉(zhuǎn)】淺談PHP5中垃圾回收算法(Garbage Collection)的演化 前言 PHP是一門托管型語言,在PHP編程中程序員不需要手工處理內(nèi)存資源的分配與釋放(使用C編寫PHP或Zend擴(kuò)展除外),這就意味著PHP本身實(shí)現(xiàn)了垃圾回收機(jī)制(Garbage C...
摘要:本書的地址篇收集了一些常見的基礎(chǔ)進(jìn)階面試題,基礎(chǔ)的面試題不再作答。如何實(shí)現(xiàn)持久化持久化,將在內(nèi)存中的的狀態(tài)保存到硬盤中,相當(dāng)于備份數(shù)據(jù)庫(kù)狀態(tài)。相當(dāng)于備份數(shù)據(jù)庫(kù)接收到的命令,所有被寫入的命令都是以的協(xié)議格式來保存的。 本書的 GitHub 地址:https://github.com/todayqq/PH... PHP 篇收集了一些常見的基礎(chǔ)、進(jìn)階面試題,基礎(chǔ)的面試題不再作答。 基礎(chǔ)篇 ...
摘要:插入一個(gè)元素時(shí)先將元素按先后順序插入數(shù)組,位置是,再根據(jù)的哈希值映射到散列表中的某個(gè)位置,將存入這個(gè)位置查找時(shí)先在散列表中映射到,得到在數(shù)組的位置,再?gòu)臄?shù)組中取出元素。目前只有兩種類型會(huì)使用這種機(jī)制。 1.變量結(jié)構(gòu) typedef struct _zval_struct zval; typedef union _zend_value { zend_long ...
摘要:本文主要是針對(duì),的話可以移步到慶哥的博客看,還有就是小菜我讀的是內(nèi)核剖析這本書。接下來我會(huì)使用到來調(diào)試源碼本文有參照博客中的部分內(nèi)容以及代碼。 前言 工作+實(shí)習(xí)快一年了,搞php后端開發(fā),一直很迷茫怎么提高自己,就先從php源碼開始吧,本人比較菜,本文章寫的比較趕時(shí)間,所以有什么錯(cuò)誤或者漏掉的地方,望各位大神指正,多交流才能成長(zhǎng)嘛,嘿嘿。本文主要是針對(duì)php7,php5的話可以移步到慶...
摘要:前言垃圾回收機(jī)制在工作中很少碰到,看到阮一峰的書中有寫,記錄下。垃圾回收機(jī)制與垃圾回收機(jī)制只考慮對(duì)象的強(qiáng)引用垃圾回收機(jī)制依賴引用計(jì)數(shù),當(dāng)計(jì)數(shù)為,則自動(dòng)回收該對(duì)象占用的內(nèi)存。里面的引用,都不計(jì)入垃圾回收機(jī)制,所以就不存在這個(gè)問題。 showImg(https://segmentfault.com/img/remote/1460000019752744); 前言:垃圾回收機(jī)制在工作中很少碰...
閱讀 2979·2021-09-22 15:18
閱讀 3400·2019-08-30 15:54
閱讀 3279·2019-08-30 15:53
閱讀 597·2019-08-30 14:12
閱讀 820·2019-08-29 17:01
閱讀 2206·2019-08-29 14:04
閱讀 1394·2019-08-29 13:09
閱讀 871·2019-08-26 17:40