zval_dtor與zval_ptr_dtor的區別

來源:互聯網
上載者:User

這兩個東西長得很像,起初我還錯誤以為一個是針對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。

 轉載自:

http://walu.sinaapp.com/?p=129

結論是什麼呢?
當我們不再需要tmp的時候,應該使用zval_ptr_dtor(&tmp);

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.