實現垃圾回收機制的整個原因是為了透過清理循環引用的變數來節省記憶體佔用。
引用計數:php變數存在一個叫"zval"的變數容器中。一個zval變數容器,除了包含變數的類型和值,還包括兩個位元組的額外資訊:is_ref和refcount。 is_ref是個bool值,用來識別這個變數是否屬於引用集合,php引擎才能把普通變數和引用變數區分開來;refcount用以表示指向這個zval變數容器的變數個數,當refcount = 0意味著該變數可被清除或回收了
<?php $a = array( 'meaning' => 'life', 'number' => 42 ); $a['life'] = $a['meaning']; xdebug_debug_zval( 'a' ); ?>
#上程式輸出如下:
a: (refcount=1, is_ref=0)=array ( 'meaning' => (refcount=2, is_ref=0)='life', 'number' => (refcount=1, is_ref=0)=42, 'life' => (refcount=2, is_ref=0)='life' )
Xdebug的輸出顯示為兩個值為'life'的zval 變數容器,其實是同一個:##
<?php $a = array( 'one' ); $a[] =& $a; xdebug_debug_zval( 'a' ); unset($a); xdebug_debug_zval( 'a' ); ?>
上例結果如下:
(refcount=1, is_ref=1)=array ( 0 => (refcount=1, is_ref=0)='one', 1 => (refcount=1, is_ref=1)=... )
上例儘管不再有某個作用域中的任何符號指向這個變數容器,由於陣列元素「1」仍然指向陣列本身,所以這個容器不能被清除。因為沒有另外的符號指向它,使用者沒有辦法清除這個結構,結果就會導致記憶體洩漏。 php會在腳本執行結束時清除這個資料結構,但在php清除之前,將耗費不少記憶體
回收週期:可用於處理循環引用導致記憶體洩漏問題。如果一個變數容器引用計數增加,它將繼續被使用,當然就不再在垃圾中;如果引用計數減少到零,所在變數容器將被清除(free)。就是說,僅在引用計數減少到非零值時,才會產生垃圾週期(garbage cycle);其次,在一個垃圾週期中,透過檢查引用計數是否減1(模擬),並且檢查哪些變數容器的引用次數是零,來發現哪一部分是垃圾
#開啟和關閉垃圾回收機制:除了修改配置zend.enable_gc ,也能分別呼叫gc_enable() 和 gc_disable()函數來開啟和關閉垃圾回收機制。另外,即使在垃圾回收機制不可用時,可能根也被記錄,這樣每次找到可能根後不檢查垃圾回收機制是否打開,記錄操作更快。呼叫gc_collect_cycles()函數可強制執行週期回收。
以上是什麼是PHP垃圾回收機制的詳細內容。更多資訊請關注PHP中文網其他相關文章!