簡述下php的垃圾回收機制

簡單描述:php中的變量存儲在變量容器zval中(c結構體),zval中除了存儲變量類型和值外,還有is_ref和refcount字段。refcount表示指向變量的元素個數,is_ref表示變量是否有別名。如果一個zval的refcount增加,它將繼續被使用,當然就不屬於垃圾。如果refcount減少爲0時,就回收該變量容器,屬於正常釋放,不屬於垃圾。如果一個zval的refcount減少到非零時(這裏包含循環引用的zval),它可能是垃圾,就會進入垃圾緩衝區。當緩衝區達到最大值後,回收算法會循環遍歷zval,判斷其是否爲垃圾,並進行釋放處理。以此解決循環引用導致的內存泄漏問題

 

內存泄漏:程序運行過程中申請了內存,但是在使用完成後沒有及時釋放的現象

 

循環引用導致的內存泄漏:當數組或對象內部子元素引用其父元素,而此時如果刪除其父元素,此變量容器並不會被刪除,因爲其子元素還在指向該變量容器,refcount > 0,但是由於沒有指向該變量容器的符號,所以無法手動清除,因此會發生內存泄漏,直到該腳本執行結束

$a = array( 'one' );
$a[] = &$a;
unset($a);

 

垃圾回收算法:每當緩衝區存滿時,PHP 會對緩衝區的所有zval遍歷進行「模擬刪除」,然後進行「模擬恢復」或者「真的刪除」。但是PHP只會對進行模擬刪除後refcount > 0 的zval進行恢復,那麼沒有進行恢復的也就是 refcount = 0 的就是垃圾了,進行真的刪除。模擬刪除簡單的說,就是對此zval中的每個元素進行一次refcount減1操作,操作完成之後,如果zval的refcount=0,那麼這個zval就是一個垃圾。模擬恢復相當於模擬刪除的逆運算了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章