一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - 深入解析PHP的引用計數機制

深入解析PHP的引用計數機制

2020-04-14 13:19PHP教程網 PHP教程

本篇文章是對PHP中的引用計數機制進行了詳細的分析介紹,需要的朋友參考下

PHP的變量聲明并賦值后,變量名存在符號表中,而值和類信息存在zval中,zval中包含四個變量,is_ref,refcount,value,type,zval源碼如下

復制代碼 代碼如下:

struct _zval_struct { 
    /* Variable information */ 
    zvalue_value value;     /* value */ 
    zend_uint refcount__gc; 
    zend_uchar type;    /* active type */ 
    zend_uchar is_ref__gc; 
};


refcount表示value地址與其相同的zval共有多少個,refcount=0時,zval被銷毀
is_ref表示一個zval是否被引用,有“0”和“1”兩種狀態

 

此處分析一下什么時候zval會被復制或者開辟新的內存空間呢
1.當is_ref=0,且refcount>1時,如果改變某個指向該zval的變量的值,會生成新zval,原zval的refcount--,例如:$a=1;$b=$a;$b=2;,zval將被復制,也就是說原先ab指向同一個zval,后來b會使用新開辟的zval

2.當is_ref=0,且refcount>1時,如果將zval賦值給某個引用變量,那么用來賦值和變量和被賦值的變量會使用同一個原zval,而其他指向原zval的變量將會指向一個新復制的zval,且refcount會被重新計算,例如:$a=1;$b=$a;$c=$a;$d=&$a;,此時ad使用原zval,bc使用新復制出來的zval

3.當is_ref=1,且refcount>1時,如果將zval復制給某個非引用變量,該非引用變量會使用一個新復制的zval,元zval的refcount不變,例如:$a=1;$b=&$a;$c=$a,那么ab使用原zval,而c使用新復制的zval
type表示該zval的值類型,宏定義如下

復制代碼 代碼如下:

#define IS_NULL     0 
#define IS_LONG     1 
#define IS_DOUBLE   2 
#define IS_BOOL     3 
#define IS_ARRAY    4 
#define IS_OBJECT   5 
#define IS_STRING   6 
#define IS_RESOURCE 7 
#define IS_CONSTANT 8 
#define IS_CONSTANT_ARRAY   9


value表示該zval的值,他也是個共同體,代碼如下

復制代碼 代碼如下:

typedef union _zvalue_value { 
    long lval;                  /* long value */ 
    double dval;                /* double value */ 
    struct { 
        char *val; 
        int len; 
    } str; 
    HashTable *ht;              /* hash table value */ 
    zend_object_value obj; 
} zvalue_value;


現在你知道php是如何類型變換的了,因為他的值存的其實是個可以代表任何類型的結構體,而具體的取值則根據type來決定是用共同體里的哪個變量來存值的

見下面的例子1

復制代碼 代碼如下:

.-----------
$a = 1;
$b = $a;
$c = $a;
.-----------
$d = &$a;
.-----------
$a = 2;
.-----------
$b = null;


查看refcount,is_ref,zval的變化
執行完第一部分后來看看輸出

1-----------------------------
a:(refcount=3, is_ref=0),int 1
b:(refcount=3, is_ref=0),int 1
c:(refcount=3, is_ref=0),int 1
可以看出來a,b,c使用同一個zval
再看執行完第二部分的

2----------------------------
a:(refcount=2, is_ref=1),int 1
b:(refcount=2, is_ref=0),int 1
c:(refcount=2, is_ref=0),int 1
d:(refcount=2, is_ref=1),int 1
注意此時a,d在一起了,他們使用同一個zval,而bc使用一個新生成的zval,同時重新計算兩個zval的refcount和is_ref
3----------------------------
a:(refcount=2, is_ref=1),int 2
b:(refcount=2, is_ref=0),int 1
c:(refcount=2, is_ref=0),int 1
d:(refcount=2, is_ref=1),int 2
可以知道ad這兩個is_ref=1的好基友的值是同時改變的
4----------------------------
a:(refcount=2, is_ref=1),int 2
b:(refcount=1, is_ref=0),null
c:(refcount=1, is_ref=0),int 1
d:(refcount=2, is_ref=1),int 2
bc由于他們的zval的is_ref=0,所以他們不是好基友,他們的值不會同時改變,于是bc的zval再次分裂,b = null c = 1

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本又大又硬又粗的视频 | 韩国日本香港毛片免费 | 办公室恋情在线 | 欧美又大又粗又爽视频 | 亚洲黄色图 | 国产肥女bbwbbw | 99午夜| 青草福利视频 | 欧美日韩亚洲区久久综合 | 欧美老妪| 欧美一区精品二区三区 | 国产一区二区在线观看美女 | 98在线视频噜噜噜国产 | 精品国产中文字幕在线视频 | 亚洲国产欧美在线人成aaaa20 | 精品一卡2卡3卡4卡5卡亚洲 | 成人网免费视频 | 午夜香蕉成视频人网站高清版 | 韩国美女被的免费视频 | 国产性片在线观看 | 99精彩视频 | 动漫肉在线观看 | 亚洲 欧美 日本 国产 高清 | 亚洲 欧美 日韩 国产 视频 | 国产肥老上视频 | 麻豆视频入口 | 亚洲欧美日韩国产一区图片 | 高清国产精品久久久久 | 日本一区二区三区在线 视频 | 成人免费福利网站在线看 | 国产成人精品视频一区二区不卡 | 亚洲国产精品自在自线观看 | 久久综合狠狠综合狠狠 | 第一国内永久免费福利视频 | 99视频观看| 窝窝午夜精品一区二区 | 韩国帅男同gay网站 韩国三级在线播放 | 国产精品久久毛片完整版 | 亚洲国产精品牛在线 | 久热人人综合人人九九精品视频 | 桥本有菜作品在线 |