zval_dtor與zval_ptr_dtor的區別

這兩個東西長得很像,起初我還錯誤覺得一個是針對zval一個針對zval*的釋放函數,唉,太天真了。這兩個函數都與zval的釋放有關,是咱們確定會常常碰到的兩個函數。 下面是二者的聲明: //zval_dtor是宏函數,最終展開後 ZEND_API   void  _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC) //zval_ptr_dtor是宏函數,最終展開後 ZEND_API  void  _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) 二者的工做都與釋放zval有關,但又有很大的區別。 好比咱們有一個zval *tmp,並且咱們已經對它進行了MAKE_STD_ZVAL等一系列操做了。 若是咱們對它使用zval_dtor會發生什麼事情呢? zval_dtor會直接把咱們的tmp的value部分即tmp->value所指的內存釋放掉。固然也可能不是直接釋放掉,而是從新交給ZendMM,由ZendMM進行從新分配或者釋放。 若是咱們對它使用zval_ptr_dtor會發生什麼事情呢? zval_ptr_dtor首先會將它的refcount減一,若是減一後refcount爲0了,便會再調用zval_dtor把tmp->value給釋放掉,而後再調用efree_rel()函數把本身tmp所指的zval類型結構體所佔的內存空間給釋放掉。 若是減一後不爲0呢?那zval_ptr_dtor便不會釋放tmp->value和tmp自己,而是通知一下GC垃圾回收器,而後返回而已。這裏你可能要問了,它通知GC垃圾回收器幹嗎,難道有基情?這個具體的細節我也說不清楚,只能從功能上來描述一下。 PHP文檔中有這麼一句話:」首先,咱們先要創建一些基本規則,若是一個引用計數增長,它將繼續被使用,固然就再也不在垃圾中。若是引用計數減小到零,所在變量容器將被清除(free)。就是說,僅僅在引用計數減小到非零值時,纔會產生垃圾週期(garbage cycle)。其次,在一個垃圾週期中,經過檢查引用計數是否減1,而且檢查哪些變量容器的引用次數是零,來發現哪部分是垃圾。」. 引用計數減小到零的時候,zval_ptr_dtor便會調用zval_dtor與efree_rel將tmp->value與tmp自己都完全真正的釋放掉了,因此不會有什麼問題。可是若是減1後不爲0,便會產生一個垃圾週期。每10000[硬編碼在源碼裏的一個值]個垃圾週期便會激活一次真正的垃圾回收機制。增長這一步的緣由是由於之前php用到的引用計數內存機制,沒法處理循環的引用內存泄漏。 關於這個機制的核心算法是一個27頁的pdf文檔,下載地址:http://www.research.ibm.com/people/d/dfb/papers/Bacon01Concurrent.pdf。 結論是什麼呢? 當咱們再也不須要tmp的時候,應該使用zval_ptr_dtor(&tmp);
相關文章
相關標籤/搜索