Wednesday, July 3, 2013

Understanding PHP's Garbage Collection

PHP uses reference counting and copy-on-write to manage memory. Copy-on-write
ensures that memory isn’t wasted when you copy values between variables, and reference
counting ensures that memory is returned to the operating system when it is no
longer needed.
To understand memory management in PHP, you must first understand the idea of a
symbol table. There are two parts to a variable—its name (e.g., $name), and its value
(e.g., "Fred"). A symbol table is an array that maps variable names to the positions of
their values in memory.
When you copy a value from one variable to another, PHP doesn’t get more memory
for a copy of the value. Instead, it updates the symbol table to indicate that “both of
these variables are names for the same chunk of memory.” So the following code doesn’t
actually create a new array:

$worker = array("Fred", 35, "Wilma");
$other = $worker; // array isn't copied
If you subsequently modify either copy, PHP allocates the required memory and makes
the copy:
$worker[1] = 36; // array is copied, value changed
By delaying the allocation and copying, PHP saves time and memory in a lot of situations.
This is copy-on-write.
Each value pointed to by a symbol table has a reference count, a number that represents
the number of ways there are to get to that piece of memory. After the initial assignment
of the array to $worker and $worker to $other, the array pointed to by the symbol table
entries for $worker and $other has a reference count of 2.1 In other words, that memory
can be reached two ways: through $worker or $other. But after $worker[1] is changed,
PHP creates a new array for $worker, and the reference count of each of the arrays is
only 1.
When a variable goes out of scope, such as function parameters and local variables do
at the end of a function, the reference count of its value is decreased by one. When a
variable is assigned a value in a different area of memory, the reference count of the old
value is decreased by one. When the reference count of a value reaches 0, its memory
is released. This is reference counting.
Reference counting is the preferred way to manage memory. Keep variables local to
functions, pass in values that the functions need to work on, and let reference counting
take care of the memory management. If you do insist on trying to get a little more
information or control over freeing a variable’s value, use the isset() and unset()
functions.
To see if a variable has been set to something—even the empty string—use isset():
$s1 = isset($name); // $s1 is false
$name = "Fred";
$s2 = isset($name); // $s2 is true
Use unset() to remove a variable’s value:
$name = "Fred";
unset($name); // $name is NULL

0 comments:

Post a Comment