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