溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

php引用計數怎么實現垃圾回收

發(fā)布時間:2022-05-12 14:39:57 來源:億速云 閱讀:111 作者:iii 欄目:大數據

這篇文章主要講解了“php引用計數怎么實現垃圾回收”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“php引用計數怎么實現垃圾回收”吧!

實現說明

1、給對象添加引用計數器,每次在某個地方引用計數器的值都會增加。每當引用失效時,計數器的值就會減一。

變量value的refcount減一后等于0的話,這個value就會被釋放,不是垃圾。垃圾回收器不處理。

變量value的refcount減一后大于0以上的話,這個value被認為不能釋放,有可能成為垃圾。

2、垃圾回收器收集可能的垃圾,達到一定數量后啟動垃圾鑒定程序,釋放真正的垃圾。

實例

<?php
// PHP垃圾回收機制案例: 參考php手冊
 
 
// --------------------標量類型--------------------
// tip:每個php變量存在一個叫"zval"的變量容器中,該容器中包含變量的類型和值,"is_ref":是否是引用變量,"refcount":引用計數
 
// ex:生成一個新的 zval容器
$a = 'new string';
// ex:顯示 zval容器 信息
xdebug_debug_zval('a'); // a:(refcount=1, is_ref=0),string 'new string' (length=10)
 
// ex:增加 zval容器的引用計數
$c = $b = $a;
xdebug_debug_zval('a'); // a:(refcount=3, is_ref=0),string 'new string' (length=10)
 
 
xdebug_debug_zval('b'); // b:(refcount=3, is_ref=0),string 'new string' (length=10)
xdebug_debug_zval('c'); // c:(refcount=3, is_ref=0),string 'new string' (length=10)
// tip:此時只有一個容器, 因為當沒必要時,php不會去復制已生成的變量容器
// 此時這個變量容器被變量 a ,變量 b和變量c關聯.
 
 
unset($b); // ex:減少引用計數
xdebug_debug_zval('a'); // a:(refcount=2, is_ref=0),string 'new string' (length=10)
// tip:unset 刪除變量時,refcount 變量計數減一,此時只有$a,$b 指向該變量容器
 
 
unset($a);
unset($c);
var_dump($a);
// tip:此時 recount為 0,變量被刪除
// 當recount 變?yōu)?nbsp;0 時,包含類型和值的這個變量容器就會從內存中刪除。
 
 
// --------------------復合類型--------------
echo '--------------復合類型------------<br/>';
 
$a = array(
    'name' => 'junior',
    'age'  => 18
);
xdebug_debug_zval('a');
// a:(refcount=1, is_ref=0),
// array (size=2)
//   'name' => (refcount=1, is_ref=0),string 'junior' (length=6)
//   'age' => (refcount=1, is_ref=0),int 18
 
 
// ex:添加一個已經存在的元素到數組中
$a['love'] =  $a['name'];
xdebug_debug_zval('a');
// a:(refcount=1, is_ref=0),
// array (size=3)
//   'name' => (refcount=2, is_ref=0),string 'junior' (length=6)
//   'age' => (refcount=1, is_ref=0),int 18
//   'love' => (refcount=2, is_ref=0),string 'junior' (length=6)
 
 
// $a = array('one');
// xdebug_debug_zval('a');
// // $b = &$a;
// $c = $a;
// $b = &$c;
 
// xdebug_debug_zval('b');
// xdebug_debug_zval('c');
// xdebug_debug_zval('a');
 
 
 
// 清理變量容器問題
echo '------------內存泄漏問題-----------<br/>';
$a = array('one');
xdebug_debug_zval('a');
// a:(refcount=1, is_ref=0),
// array (size=1)
//   0 => (refcount=1, is_ref=0),string 'one' (length=3)
 
$a[] = &$a;
xdebug_debug_zval('a');
// a:(refcount=2, is_ref=1),
// array (size=2)
//   0 => (refcount=1, is_ref=0),string 'one' (length=3)
//   1 => (refcount=2, is_ref=1),
//     &array
 
// unset($a);
// (refcount=1, is_ref=1)=array (
//     0 => (refcount=1, is_ref=0)='one',
//     1 => (refcount=1, is_ref=1)=...
//  )
 
// tip: unset($a) 后引用計數減一,盡管不再有某個作用域中的任何符號指向這個結構(就是變量容器),
// 由于數組元素"1"仍然指向數組本身,所以這個容器不能被清除
// 因為沒有另外的符號指向它,用戶沒有辦法清除這個結構,結果就會導致內存泄漏
// 慶幸的是, php將在腳本執(zhí)行結束時清除這個數據結構, 但是在php清除之前,將耗費不少內存.
// 同樣的情況也會發(fā)生在對象上,實際上對象更有可能出現這種情況,因為對象總是隱式的被引用。

感謝各位的閱讀,以上就是“php引用計數怎么實現垃圾回收”的內容了,經過本文的學習后,相信大家對php引用計數怎么實現垃圾回收這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI