Zend PHP 7 Certification – Basics – Performance

This post covers the Performance section of the PHP Basics chapter when studying for the Zend PHP 7 Certification.

There are two major areas in which performance is affected in PHP. The first area is reduced memory usage, and the second area is run-time delay when the garbage collection mechanism performs its memory cleanups.

Reduced Memory Usage

PHP like with most programming languages use resources. Over time, there may be a build up of these resources that need to be ‘cleaned up’. PHP has its own garbage collection process.

When a program ends, the program and any resources that it has tied up will disappear and the total space available will expand back to its maximum size. But what happens to the resources when programs such as daemons are running forever?

Firstly, let’s take a look at some of the steps that PHP uses to free up resources.

When a scope of action ends the resources are freed up. You may have used the unset() function to free up a resource at any time.

Functions and methods establish a scope of action, and so are very useful for establishing when memory usage should begin and end. Functions and methods are therefore preferred over global entities.

PHP keeps track of how many entities are using a given variable using a technique called reference counting.

When a variable is created in a PHP script, PHP creates a container called a zval that consists of the value assigned to that variable plus two other pieces of information: is_ref and refcount.

  • is_ref – This is a true/false value that indicates if the variable is part of a reference set, thus helping PHP to tell if this is a simple variable or a reference.
  • refcount – This is a numeric value indicating how many different variables are using this value

If you have the Xdebug extension installed, you can view the zval container using the xdebug_debug_zval() function.

$someVar = 'Some value';
xdebug_debug_zval('someVar');

// Outputs:
someVar:
(refcount=1, is_ref=0),string 'Some value' (length=10)

If we were to assign the $someVar variable to another variable like the below, the refcount will increment by 1.

$someVar = 'Some value';
$b = $someVar;
xdebug_debug_zval('someVar');

// Outputs:
someVar:
(refcount=2, is_ref=0),string 'Some value' (length=10)

Things get a tad more complex with compound types such as arrays and objects, for example, if we use an array with another array.

In this case, the refcount for an array value is set to 1 when the original array value is set, then incremented to 2 when the array is associated with another array. If the scope of use of the second array ends, we decrement the refcount by 1. So although the value itself is no longer associated with anything, the zval container that represents it still has a refcount greater than zero, causing a memory leak.

Luckily these leaks are cleared up by PHP at the end of the request and might not be a bit issue if there are only a few occasions where this happens. However for long running processes, these should be addressed.

By default garbage collection is enabled. There is, however, a php.ini setting that allows you to change this: zend.enable_gc. Or by using the function gc_disable().

The gc_collect_cycles() function will force the collection of any existing garbage cycles.

Run-time Delay

The second area where the garbage collection mechanism influences performance is the time taken when the garbage collection mechanism kicks in to free the “leaked” memory.

In general the garbage collector in PHP will only cause a slowdown when the cycle collecting algorithm actually runs, whereas in normal (smaller) scripts there should be no performance hit at all.

View the other sections:

Note: This article is based on PHP version 7.0.