婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 詳解PHP的引用計數

詳解PHP的引用計數

熱門標簽:衡水外呼系統平臺 地圖標注平臺怎么給錢注冊 常州地圖標注服務商 注冊400電話申請 百度商鋪地圖標注 釘釘打卡地圖標注 新河科技智能外呼系統怎么樣 福州人工外呼系統哪家強 安裝電銷外呼系統

什么是引用計數

在PHP的數據結構中,引用計數就是指每一個變量,除了保存了它們的類型和值之外,還額外保存了兩個內容,一個是當前這個變量是否被引用,另一個是引用的次數。為什么要多保存這樣兩個內容呢?當然是為了垃圾回收(GC)。也就是說,當引用次數為0的時候,這個變量就沒有再被使用了,就可以通過 GC 來進行回收,釋放占用的內存資源。任何程序都不能無限制的一直占用著內存資源,過大的內存占用往往會帶來一個嚴重的問題,那就是內存泄露,而 GC 就是PHP底層自動幫我們完成了內存的銷毀,而不用像 C 一樣必須去手動地 free 。

怎么查看引用計數?

我們需要安裝 xdebug 擴展,然后使用 xdebug_debug_zval() 函數就可以看到指定內存的詳細信息了,比如:

$a = "I am a String";
xdebug_debug_zval('a');
// a: (refcount=1, is_ref=0)='I am a String'

從上述內容中可以看出,這個 $a 變量的內容是 I am a String 這樣一個字符串。而括號中的 refcount 就是引用次數,is_ref 則是說明這個變量是否被引用。我們通過變量賦值來看看這個兩個參數是如何變化的。

$b = $a;
xdebug_debug_zval('a');
// a: (refcount=1, is_ref=0)='I am a String'

$b = $a;
xdebug_debug_zval('a');
// a: (refcount=2, is_ref=1)='I am a String'

當我們進行普通賦值后,refcount 和 is_ref 沒有任何變化,但當我們進行引用賦值后,可以看到 refcount 變成了2,is_ref 變成了1。這也就是說明當前的 \a 變量被引用賦值了,它的內存符號表服務于a變量被引用賦值了,它的內存符號表服務于a 和 $b 兩個變量。

$c = $a;
xdebug_debug_zval('a');
// a: (refcount=3, is_ref=1)='I am a String'

unset($c, $b);
xdebug_debug_zval('a');
// a: (refcount=1, is_ref=1)='I am a String'

$b = $a;
$c = $a;
$b = "I am a String new";
xdebug_debug_zval('a');
// a: (refcount=3, is_ref=1)='I am a String new'

unset($a);
xdebug_debug_zval('a');
// a: no such symbol

繼續增加一個 c 的引用賦值,可以看到 refcount 會繼續增加。然后 unset 掉c的引用賦值,可以看到refcount會繼續增加。然后unset掉b 和 $c 之后,refcount 恢復到了1,不過這時需要注意的是,is_ref 依然還是1,也就是說,這個變量被引用過,這個 is_ref 就會變成1,即使引用的變量都已經 unset 掉了這個值依然不變。

最后我們 unset 掉 $a ,顯示的就是 no such symbol 了。當前變量已經被銷毀不是一個可以用的符號引用了。(注意,PHP中的變量對應的是內存的符號表,并不是真正的內存地址)

對象的引用計數

和普通類型的變量一樣,對象變量也是使用同樣的計數規則。

// 對象引用計數
class A{

}
$objA = new A();
xdebug_debug_zval('objA');
// objA: (refcount=1, is_ref=0)=class A {  }

$objB = $objA;
xdebug_debug_zval('objA');
// objA: (refcount=2, is_ref=0)=class A {  }

$objC = $objA;
xdebug_debug_zval('objA');
// objA: (refcount=3, is_ref=0)=class A {  }

unset($objB);
class C{

}
$objC = new C;
xdebug_debug_zval('objA');
// objA: (refcount=1, is_ref=0)=class A {  }

不過這里需要注意的是,對象的符號表是建立的連接,也就是說,對 objC 進行重新實例化或者修改為 NULL ,并不會影響objC進行重新實例化或者修改為NULL,并不會影響objA 的內容,對象進行普通賦值操作也是引用類型的符號表賦值,所以我們不需要加 符號。

數組的引用計數

// 數組引用計數
$arrA = [
    'a'=>1,
    'b'=>2,
];
xdebug_debug_zval('arrA');
// arrA: (refcount=2, is_ref=0)=array (
//     'a' => (refcount=0, is_ref=0)=1, 
//     'b' => (refcount=0, is_ref=0)=2
// )

$arrB = $arrA;
$arrC = $arrA;
xdebug_debug_zval('arrA');
// arrA: (refcount=4, is_ref=0)=array (
//     'a' => (refcount=0, is_ref=0)=1, 
//     'b' => (refcount=0, is_ref=0)=2
// )

unset($arrB);
$arrC = ['c'=>3];
xdebug_debug_zval('arrA');
// arrA: (refcount=2, is_ref=0)=array (
//     'a' => (refcount=0, is_ref=0)=1, 
//     'b' => (refcount=0, is_ref=0)=2
// )

// 添加一個已經存在的元素
$arrA['c'] = $arrA['a'];
xdebug_debug_zval('arrA');
// arrA: (refcount=1, is_ref=0)=array (
//     'a' => (refcount=2, is_ref=1)=1, 
//     'b' => (refcount=0, is_ref=0)=2, 
//     'c' => (refcount=2, is_ref=1)=1
// )

調試數組的時候,我們會發現兩個比較有意思的事情。

一是數組內部的每個元素又有單獨的自己的引用計數。這也比較好理解,每一個數組元素都可以看做是一個單獨的變量,但數組就是這堆變量的一個哈希集合。如果在對象中有成員變量的話,也是一樣的效果。當數組中的某一個元素被 引用賦值給其他變量之后,這個元素的 refcount 會增加,不會影響整個數組的 refcount 。

二是數組默認上來的 refcount 是2。其實這是 PHP7 之后的一種新的特性,當數組定義并初始化后,會將這個數組轉變成一個不可變數組(immutable array)。為了和普通數組區分開,這種數組的 refcount 是從2開始起步的。當我們修改一下這個數組中的任何元素后,這個數組就會變回普通數組,也就是 refcount 會變回1。這個大家可以自己嘗試下,關于為什么要這樣做的問題,官方的解釋是為了效率,具體的原理可能還是需要深挖 PHP7 的源碼才能知曉。

關于內存泄露需要注意的地方

其實 PHP 在底層已經幫我們做好了 GC 機制就不需要太關心變量的銷毀釋放問題,但是,千萬要注意的是對象或數組中的元素是可以賦值為自身的,也就是說,給某個元素賦值一個自身的引用就變成了循環引用。那么這個對象就基本不太可能會被 GC 自動銷毀了。

// 對象循環引用
class D{
    public $d;
}
$d = new D;
$d->d = $d;
xdebug_debug_zval('d');
// d: (refcount=2, is_ref=0)=class D { 
//     public $d = (refcount=2, is_ref=0)=... 
// }

// 數組循環引用
$arrA['arrA'] = $arrA;
xdebug_debug_zval('arrA');
// arrA: (refcount=2, is_ref=1)=array (
//     'a' => (refcount=0, is_ref=0)=1, 
//     'b' => (refcount=0, is_ref=0)=2, 
//     'arrA' => (refcount=2, is_ref=1)=...
// )

不管是對象還是數組,在打印調試時出現了 ... 這樣的省略號,那么你的程序中就出現了循環引用。所以這個問題應該是我們在日常開發中應該時刻關注的問題。

總結

引用計數是了解垃圾回收機制的前提條件,而且正是因為現代語言中都有一套類似的垃圾回收機制才讓我們的編程變得更加容易且安全。那么有人說了,日常開發根本用不到這些呀?用不到不代表不應該去學習,就像循環引用這個問題一樣,當代碼中充斥著大量的類似代碼時,系統崩潰只是遲早的事情,所以,這些知識是我們向更高級的程序進階所不可或缺的內容。

測試代碼: github.com/zhangyue050…

以上就是詳解PHP的引用計數的詳細內容,更多關于PHP的引用計數的資料請關注腳本之家其它相關文章!

您可能感興趣的文章:
  • PHP 引用的概念
  • php的對象傳值與引用傳值代碼實例講解
  • php傳值和傳引用的區別點總結
  • php 多個變量指向同一個引用($b = &$a)用法分析
  • php引用和拷貝的區別知識點總結
  • php中對象引用和復制實例分析
  • PHP實現無限極分類的兩種方式示例【遞歸和引用方式】
  • PHP中引用類型和值類型功能與用法示例
  • PHP 弱引用的相關總結

標簽:白城 克拉瑪依 六安 鶴崗 唐山 柳州 鷹潭 遼陽

巨人網絡通訊聲明:本文標題《詳解PHP的引用計數》,本文關鍵詞  詳解,PHP,的,引用,計數,詳解,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《詳解PHP的引用計數》相關的同類信息!
  • 本頁收集關于詳解PHP的引用計數的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    久久精品国产第一区二区三区| 亚洲免费在线观看| 欧美午夜精品久久久久久孕妇| 成人午夜在线播放| 国产成人一区二区精品非洲| 国产精品亚洲视频| 国产一区二区三区国产| 国产精品18久久久久久久久久久久| 国产精品一区二区视频| 国产一区不卡视频| 99久久免费精品高清特色大片| 99riav一区二区三区| 91黄色激情网站| 欧美一区二区三区电影| 精品国产在天天线2019| 久久一区二区三区国产精品| 中文字幕av资源一区| 国产精品国产三级国产三级人妇 | 国产麻豆精品一区二区| 狠狠色伊人亚洲综合成人| 国产在线国偷精品免费看| 成人网在线播放| 91小视频在线观看| 3d动漫精品啪啪一区二区竹菊| 精品少妇一区二区三区在线播放 | 欧美日韩高清一区二区不卡 | 亚洲精品视频在线观看网站| 天堂精品中文字幕在线| 久久69国产一区二区蜜臀| 成人小视频在线观看| 欧美影院一区二区| 久久噜噜亚洲综合| 一级做a爱片久久| 精品亚洲porn| 在线免费观看成人短视频| 日韩欧美你懂的| 亚洲精品免费看| 国产精品一区二区黑丝 | 日本中文一区二区三区| 波多野结衣精品在线| 欧美精品丝袜中出| 国产精品沙发午睡系列990531| 免费在线欧美视频| 色天天综合久久久久综合片| 精品99999| 亚洲国产精品久久艾草纯爱| 成人一区二区三区在线观看| 欧美一区二区精品在线| 一区二区三区av电影 | 亚洲综合色婷婷| 国产成人在线视频网站| 欧美草草影院在线视频| 亚洲综合一二三区| 91在线免费视频观看| www一区二区| 寂寞少妇一区二区三区| 欧美日韩国产精品自在自线| 1000精品久久久久久久久| 国产精品自产自拍| 精品国产一区二区三区久久影院| 亚洲小说欧美激情另类| 东方aⅴ免费观看久久av| 精品福利在线导航| 蜜桃视频一区二区三区| 欧美日韩亚洲丝袜制服| 亚洲激情在线播放| 欧美综合欧美视频| 一区二区三区不卡视频在线观看 | 国产麻豆精品视频| 久久精品人人做| 国内外成人在线视频| 日韩精品一区二区三区在线播放| 婷婷激情综合网| 日韩一区二区三区免费看| 日韩福利视频网| 日韩欧美亚洲一区二区| 激情六月婷婷久久| 欧美mv和日韩mv国产网站| 国产伦精品一区二区三区免费| 精品国产露脸精彩对白| 国产精品一二三区在线| 一区在线播放视频| 色8久久精品久久久久久蜜| 亚洲黄色小视频| 国产欧美中文在线| 精品不卡在线视频| 精品在线亚洲视频| 欧美va亚洲va香蕉在线| 精品一区二区免费看| 国产精品无圣光一区二区| av成人老司机| 午夜久久久久久久久久一区二区| 欧美一卡2卡3卡4卡| 极品少妇xxxx精品少妇| 国产婷婷精品av在线| 欧洲av一区二区嗯嗯嗯啊| 日本va欧美va精品发布| 久久久三级国产网站| 99v久久综合狠狠综合久久| 亚洲国产日韩av| 日韩免费观看2025年上映的电影| 国产成人免费视| 亚洲免费观看高清在线观看| 91精品视频网| 成人在线视频首页| 日av在线不卡| 国产精品丝袜黑色高跟| 91精品国产一区二区三区蜜臀| 国产精品18久久久久久久久| 亚洲一区二区五区| 欧美精品一区二区三区视频| 91在线一区二区三区| 国产一区三区三区| 日韩精品成人一区二区三区| 亚洲欧洲日韩av| 日韩精品综合一本久道在线视频| 91麻豆国产福利在线观看| 国产在线麻豆精品观看| 亚洲午夜影视影院在线观看| 欧美激情中文字幕一区二区| 欧美日韩精品一区二区三区四区| 国产v日产∨综合v精品视频| 香蕉成人伊视频在线观看| 亚洲色图一区二区三区| 久久精品一区八戒影视| 91精品国产综合久久久久久 | 国产老妇另类xxxxx| 亚洲尤物视频在线| 成人免费在线视频| 国产日韩精品视频一区| 精品久久人人做人人爰| 欧美一区二区人人喊爽| 9191国产精品| 51精品视频一区二区三区| 91福利视频久久久久| 97精品国产97久久久久久久久久久久 | 99精品视频一区二区三区| 国产精品资源在线看| 久久精品国产一区二区三| 日韩成人免费看| 免费美女久久99| 美女被吸乳得到大胸91| 日韩av电影免费观看高清完整版| 午夜亚洲福利老司机| 亚洲自拍偷拍欧美| 亚洲成人av免费| 日韩黄色免费网站| 另类小说色综合网站| 久久97超碰国产精品超碰| 韩日精品视频一区| 国产精品91一区二区| 国产91丝袜在线18| 91丨porny丨在线| 在线观看一区日韩| 3d动漫精品啪啪| 久久亚洲一区二区三区明星换脸| 欧美成人精品1314www| 精品国产伦一区二区三区免费| 亚洲精品一区二区在线观看| 久久综合色鬼综合色| 国产日韩成人精品| 亚洲欧洲综合另类| 日精品一区二区| 国产在线精品视频| 97久久精品人人做人人爽| 欧美在线免费播放| 欧美大尺度电影在线| 国产精品视频你懂的| 亚洲一区二区三区中文字幕在线| 日韩精品亚洲专区| 国内精品久久久久影院色| 99国产精品一区| 欧美精品在线一区二区| 国产日韩欧美高清在线| 亚洲一区在线观看视频| 精品亚洲成a人在线观看| 91啪亚洲精品| 26uuu亚洲综合色| 亚洲欧美一区二区三区极速播放| 午夜精品久久久久久久久久| 国产一本一道久久香蕉| 在线观看91精品国产入口| 久久久久久电影| 午夜精品久久久久久久久| 成人av中文字幕| 日韩视频国产视频| 亚洲精品国产视频| 国产精品77777竹菊影视小说| 欧美日韩在线三区| 中文字幕免费不卡| 久久超碰97人人做人人爱| 日本精品一区二区三区四区的功能| 精品日韩在线观看| 亚洲一区二区在线免费看| 成人一区二区视频| 26uuu欧美| 免费观看日韩av| 欧美色综合网站| 亚洲欧美日韩综合aⅴ视频| 国产精品99久久久久久有的能看|