PHP Reference Counter
Overview
I recently looked at the reference counter section in PHP, which was first dizzy by a variety of methods. After reading the blog and analysis, I summarized a popular explanation to help me remember it well, I also hope to help readers. Here I share a blog post, is a more orthodox explanation: Reference of PHP variables (http://hilojack.sinaapp.com /? P = 1392 ).
Suggestions
To study the changes in the PHP reference counter, you can learn by installing the Xdebug extension. After installation, you can directly call xdebug_debug_zval ('var') to view the reference counter of the variable $ var.
Basic knowledge
When talking about the reference counter, you need to understand the storage and reference counting mechanisms of variables in PHP. The reference counting is of course memory saving, without affecting the semantic correctness, share a memory value space (also called a variable container) with multiple variable symbols ). When does the reference count change:Assignment. There are two types of Value assignment: Value assignment and Reference Assignment. What is hard to understand is the reference value assignment. Another function of reference counting is to indicate when the same space can be shared and when variable separation is required (another open-up space ).
General Explanation
For ease of understanding and memory, I will give a general explanation of the various situations in the assignment. Do not sit in the room with the actual situation ,.
& No. IsIntegration, Can be equivalent to marriage, but PHP allows many people to get married together (that is, a polygenous or polyandry), this is more abnormal. Note:To get married, you must live together., Separation is not acceptable. In addition to marriage, there is also a form of shared rent. Shared rent is also common, but there is noLinkIt is reasonable to allow multiple users to share the rent. Of course, there is another case of living alone, which is easier to understand. The following example shows the correspondence between the value assignment statement and the three states:
Scenario 1:
$ A = "a"; // $ a living alone, is_ref = 0, refcount = 1; $ B = $ a; // $ a and $ B rent together, is_ref = 0, refcount = 2;
Scenario 2:
$ A = "a"; // $ a lives alone, is_ref = 0, refcount = 1; $ B = & $ a; // $ a and $ B get married, is_ref = 1, refcount = 2;
As shown above, is_ref can be understood as a marriage certificate. = 1 indicates that two or more variables are married, and = 0 is not married (you can share a rent or live together ), refcount indicates how many variables are living together. = 1 indicates living alone.> 1 indicates living together. (Remember, to get married, you must live together, but not necessarily in a marriage relationship ).
Next, we will analyze the variable variation relationship when assigning values:
Scenario 1:
$ A = "a"; // $ a living alone, is_ref = 0, refcount = 1; $ B = $ a; // $ a and $ B rent together, is_ref = 0, refcount = 2; $ va = "B"; // $ va living alone, is_ref = 0, refcount = 1; $ vb = $ va; // $ va and $ vb rent together, is_ref = 0, refcount = 2; $ a = $ va; // $ a is single, and $ va is also single. Therefore, $ a moves to live with $ va. Now $, $ va, $ vb: $ a: is_ref = 0, refcount = 3, string = "xyz" $ B: is_ref = 0, refcount = 1, string = "qwe" $ va: is_ref = 0, refcount = 3, string "xyz" $ vb: is_ref = 0, refcount = 3, string "xyz"
Scenario 2:
$ A = "a"; // $ a lives alone, is_ref = 0, refcount = 1; $ B = & $ a; // $ a and $ B get married, is_ref = 1, refcount = 2; $ va = "B"; // $ va living alone, is_ref = 0, refcount = 1; $ vb = $ va; // $ va and $ vb shared rent, is_ref = 0, refcount = 2; $ a = $ va; // $ a is married and $ a cannot be moved out independently, assign a value to copy the value of $ va to $ a. OthersLinkUnchanged $ a: is_ref = 1, refcount = 2, string = "xyz" $ B: is_ref = 1, refcount = 2, string = "xyz" $ va: is_ref = 0, refcount = 2, string "xyz" $ vb: is_ref = 0, refcount = 2, string "xyz"
Scenario 3:
$ A = "a"; // $ a lives alone, is_ref = 0, refcount = 1; $ B = & $ a; // $ a and $ B get married, is_ref = 1, refcount = 2; $ va = "B"; // $ va living alone, is_ref = 0, refcount = 1; $ vb = & $ va; // $ va and $ vb get married, is_ref = 1, refcount = 2; $ a = $ va; // $ a is married, which is the same as scenario 2. Copy the value, after the relationships remain unchanged, values: $ a: is_ref = 1, refcount = 2, string = "xyz" $ B: is_ref = 1, refcount = 2, string = "xyz" $ va: is_ref = 1, refcount = 2, string "xyz" $ vb: is_ref = 1, refcount = 2, string "xyz"
Scenario 4:
$ A = "qwe"; // $ a living alone, is_ref = 0, refcount = 1; $ B = $ a; // $ a living with $ B, is_ref = 0, refcount = 2; $ va = "xyz"; // $ va living alone, is_ref = 0, refcount = 1; $ vb = & $ va; // $ va and $ vb get married, is_ref = 1, refcount = 2; $ a = $ va; // $ a wants to live with $ va instead of getting married ), but $ va is married, so $ a can only be moved out of $ B and re-allocated to a house with the same value as $ va (term: Variable Separation ); $ a: is_ref = 0, refcount = 1, string = "xyz" $ B: is_ref = 0, refcount = 1, string = "qwe" $ va: is_ref = 1, refcount = 2, string "xyz" $ vb: is_ref = 1, refcount = 2, string "xyz"
Scenario 5:
$ A = "qwe"; // $ a living alone, is_ref = 0, refcount = 1; $ B = $ a; // $ a living with $ B, is_ref = 0, refcount = 2; $ va = "xyz"; // $ va living alone, is_ref = 0, refcount = 1; $ vb = $ va; // $ va living together with $ vb, is_ref = 0, refcount = 2; $ a = & $ va; // $ a wants to marry $ va. Now $ a and $ va are single but have roommates, therefore, they moved from the original place and then divided into new houses. After the value is the same as that of $ va, $ a: is_ref = 1, refcount = 2, string = "xyz" $ B: is_ref = 0, refcount = 1, string = "qwe" $ va: is_ref = 1, refcount = 2, string "xyz" $ vb: is_ref = 0, refcount = 1, string "xyz"
Scenario 6:
$ A = "qwe"; // $ a living alone, is_ref = 0, refcount = 1; $ B = $ a; // $ a living with $ B, is_ref = 0, refcount = 2; $ va = "xyz"; // $ va living alone, is_ref = 0, refcount = 1; $ vb = & $ va; // $ va and $ vb get married, is_ref = 1, refcount = 2; $ a = & $ va; // $ a wants to marry $ va, but $ va is married, while $ a is single, so $ a moved to live with $ va. $ va now has two spouses: $ vb and $ a assigned values: $ a: is_ref = 1, refcount = 3, string = "xyz" $ B: is_ref = 0, refcount = 1, string = "qwe" $ va: is_ref = 1, refcount = 3, string "xyz" $ vb: is_ref = 1, refcount = 3, string "xyz"
Scenario 7:
$ A = "qwe"; // $ a lives alone, is_ref = 0, refcount = 1; $ B = & $ a; // $ a and $ B get married, is_ref = 1, refcount = 2; $ va = "xyz"; // $ va living alone, is_ref = 0, refcount = 1; $ vb = $ va; // $ va and $ vb live together, is_ref = 0, refcount = 2; $ a = & $ va; // $ a wants to marry $ va, however, $ a is married and $ va is single. The solution is to marry $ a after divorce and assign a value to $ va after $ va is moved from the place where it is shared with $ vb: $ a: is_ref = 1, refcount = 2, string = "xyz" $ B: is_ref = 0, refcount = 1, string = "qwe" $ va: is_ref = 1, refcount = 2, string "xyz" $ vb: is_ref = 0, refcount = 1, string "xyz"
Scenario 8:
$ A = "qwe"; // $ a lives alone, is_ref = 0, refcount = 1; $ B = & $ a; // $ a and $ B get married, is_ref = 1, refcount = 2; $ va = "xyz"; // $ va living alone, is_ref = 0, refcount = 1; $ vb = & $ va; // $ va and $ vb get married, is_ref = 1, refcount = 2; $ a = & $ va; // $ a wants to marry $ va, but $ a and $ va are both married. Who is divorced? $ !, Because $ a takes the initiative to marry $ va, // $ a lives with $ va after divorce, $ va now has two spouses: $ vb and $ a assigned values: $: is_ref = 1, refcount = 3, string = "xyz" $ B: is_ref = 0, refcount = 1, string = "qwe" $ va: is_ref = 1, refcount = 3, string "xyz" $ vb: is_ref = 1, refcount = 3, string "xyz"
The above analyzes various situations of simple variable assignment, excluding self-reference. Overview:
A simple assignment is cohabiting. You need to check the is_ref (that is, whether it is married) of the variable on the left of the equal sign. If is_ref = 1, the value is copied; otherwise, the Order on the left is considered, can I share the same bucket (cohabiting) with the right variable without allocating additional memory? In this case, check whether the right side is married. If so, you cannot cohabit and separate the variables, if the variable on the right is single, the same memory is directly shared. All cows follow the COW principle.
The reference value assignment is a combination. You need to first check the reference of the variable on the right. If is_ref = 1, refcount ++ is used directly, if the right side is not referenced (is_ref = 0), you also need to check whether the right side is living alone. If it is living alone, the left and right variables share the right variable space, otherwise, the variables on the right are separated from the original place and new spaces are opened on the left. As long as the value is referenced, the left-side variables always need to be separated from the previously combined or shared variables.