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
$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
$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
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.
With all this copying and referencing, there are a couple of combinations of events that
can't be handled by clever manipulation of
refcount. Consider this block of
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
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: www.samspublishing.com/title/067232704x
Created: March 27, 2003
Revised: June 19, 2006