How to Manage Memory in PHP | 4 | WebReference

How to Manage Memory in PHP | 4

How to Manage Memory in PHP

Change on Write

The concept of reference counting also creates a new possibility for data manipulation in the form of what userspace scripters actually think of in terms of "referencing". Consider the following snippet of userspace code:

Being experienced in the ways of PHP code, you'll instinctively recognize that the value of $a will now be 6 even though it was initialized to 1 and never (directly) changed. This happens because when the engine goes to increment the value of $b by 5, it notices that $b is a reference to $a and says, "It's okay for me to change the value without separating it, because I want all reference variables to see the change."

But how does the engine know? Simple, it looks at the fourth and final element of the zval struct: is_ref.This is just a simple on/off bit value that defines whether the value is, in fact, part of a userspace-style reference set. In the previous code snippet, when the first line is executed, the value created for $a gets a refcount of 1, and an is_ref value of 0 because its only owned by one variable ($a), and no other variables have a change on write reference to it. At the second line, the refcount element of this value is incremented to 2 as before, except that this time, because the script included an ampersand to indicate full-reference, the is_ref element is set to 1.

Finally, at the third line, the engine once again fetches the value associated with $b and checks if separation is necessary. This time the value is not separated because of a check not included earlier. Here's the refcount check portion of get_var_and_separate() again, with an extra condition:

This time, even though the refcount is 2, the separation process is short-circuited by the fact that this value is a full reference. The engine can freely modify it with no concern about the values of other variables appearing to change magically on their own.

Separation Anxiety

With all this copying and referencing, there are a couple of combinations of events that can't be handled by clever manipulation of is_ref and refcount. Consider this block of PHP code:

Here you have a single value that needs to be associated with three different variables, two in a change-on-write full reference pair, and the third in a separable copy-on-write context. Using just is_ref and refcount to describe this relationship, what values will work?

The answer is: none. In this case, the value must be duplicated into two discrete zval*s, even though both will contain the exact same data (see Figure 3.2).

Similarly, the following code block will cause the same conflict and force the value to separate into a copy (see Figure 3.3).

Notice here that in both cases here, $b is associated with the original zval object because at the time separation occurs, the engine doesn't know the name of the third variable involved in the operation.


PHP is a managed language. On the userspace side of things, this careful control of resources and memory means easier prototyping and fewer crashes. After you delve under the hood though, all bets are off and it's up to the responsible developer to maintain the integrity of the runtime environment.

This Chapter is excerpted from the new book titled, "Extending and Embedding PHP", authored by Sara Golemon, published by Sams in the Developer's Library, May, 2006. Copyright 2006 by Sams Publishing. All rights reserved, reprinted with permission from Pearson Education. Content excerpt represents Chapter 3, pages 35 to 46. To learn more, please visit:


Created: March 27, 2003
Revised: June 19, 2006