Understanding PHP’s Garbage Collection and Reference Counting: Deep Dive with Code Examples
This article explains how PHP’s automatic garbage collector works, detailing reference‑counting, zval structures, handling of scalar and composite types, cycle detection, configuration options, and practical debugging techniques using Xdebug and code samples.
Concept
PHP’s garbage collection is automatic and relies on a built‑in collector. When a PHP object is no longer referenced it becomes garbage; the collector periodically scans memory, marks unreferenced objects, and frees their memory.
The mechanism uses reference counting . Each object has a counter that increments when a variable is assigned ( +1) and decrements when the variable no longer references the object ( -1). When the counter reaches zero, the object is freed.
For cyclic references the collector cannot free the objects, so PHP allows manual breaking of references by assigning null to the variable, forcing the counter to zero.
Reference Counting Basics
PHP variables are stored in a container called zval. Besides type and value, a zval holds two bits: is_ref (whether the variable is part of a reference set) and refcount (how many symbols point to this zval).
Creating a new scalar variable creates a single zval with refcount=1 and is_ref=false. Example:
<?php
$a = "new string";Running xdebug_debug_zval('a'); shows: a: (refcount=1, is_ref=0)='new string' Assigning the variable to another name increments the refcount:
<?php
$a = "new string";
$b = $a;
xdebug_debug_zval('a'); a: (refcount=2, is_ref=0)='new string'Calling unset($a) or letting the scope end reduces the counter, and when it reaches zero the zval is destroyed.
Composite Types
Arrays and objects store their elements in separate symbol tables, creating multiple zvals. Example of an array:
<?php
$a = array('meaning' => 'life', 'number' => 42);
xdebug_debug_zval('a'); a: (refcount=1, is_ref=0)=array (
'meaning' => (refcount=1, is_ref=0)='life',
'number' => (refcount=1, is_ref=0)=42
)Adding an element that references an existing element increases the refcount of the shared zval:
<?php
$a = array('meaning' => 'life', 'number' => 42);
$a['life'] = $a['meaning'];
xdebug_debug_zval('a'); a: (refcount=1, is_ref=0)=array (
'meaning' => (refcount=2, is_ref=0)='life',
'number' => (refcount=1, is_ref=0)=42,
'life' => (refcount=2, is_ref=0)='life'
)When an array element is unset, the refcount of the referenced zval decreases, and the container is removed once the count reaches zero.
Cleanup Issues
Even without any external symbols, a structure may remain uncollected if an array element still references the array itself, creating a memory leak. This is problematic for long‑running scripts or massive test suites, where such leaks can consume gigabytes of RAM.
Cycle Collection
Since PHP 5.3, a cyclic‑GC algorithm is integrated to break reference cycles. The algorithm works on a "root buffer" that stores possible garbage roots (zval containers). When the buffer fills (default 10 000 entries), a simulated delete‑restore process runs:
Simulate deleting each purple (possible‑root) variable, decreasing refcounts of reachable variables.
If a variable’s refcount drops to zero, it is also simulated for deletion.
After the simulation, restore variables whose refcount is still > 0 (black nodes).
Remaining blue nodes are truly unreachable and are finally freed.
Configuration
The GC can be toggled via zend.enable_gc in php.ini, or at runtime with gc_enable() and gc_disable(). Manual collection is possible with gc_collect_cycles(), which returns the number of cycles reclaimed.
Even when disabled, possible roots are still recorded because tracking them is cheaper than checking the GC state on each potential root.
For high‑performance sections of an application you may disable the GC, but you should invoke gc_collect_cycles() beforehand to empty the root buffer and avoid hidden leaks.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
