PHP浅析PHPの参照カウントメカニズム

5132 ワード

PHPの変数が宣言されて付与されると、変数名はシンボルテーブルに存在し、値とクラス情報はzvalに存在し、zvalには4つの変数が含まれ、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」の2つの状態がある.
ここでは、zvalがコピーされたり、新しいメモリ領域が開かれたりするのはいつですか?
1.is_ref=0、refcount>1の場合、zvalを指す変数の値を変更すると、元のzvalのrefcount--が生成されます.たとえば、$a=1;$b=$a;$b=2;,zvalはコピーされます.つまり、abは同じzvalを指していましたが、bは新しいzvalを使用します.
2.is_ref=0、refcount>1の場合、参照変数にzvalを割り当てると、値と変数と値を割り当てるための変数は同じ元のzvalを使用します.元のzvalを指す他の変数は、新しくコピーされたzvalを指し、$a=1、$b=$a;$c=$a;$d=&$a;,このときadは元のzvalを使用し,bcは新しくコピーしたzvalを使用する.
3.is_ref=1、refcount>1の場合、zvalを非参照変数にコピーすると、その非参照変数は、$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を参照
1.-----------

$a = 1;

$b = $a;
$c = $a;

2.-----------
$d = &$a; 3.----------- $a = 2;

4.-----------
$b = null;

refcount,is_の表示ref,zvalの変化
第1部を実行したら出力を見てください
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部の実行を見てみましょう
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を使って、同時に2つの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の2つの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になります.
 
The End
参照CSDN phpkernel blog:http://blog.csdn.net/phpkernel/article/details/5732784