Inside PHP: Understanding the zval Structure and Memory Management
This article explains PHP's core zval structure, how different variable types are stored, and the mechanisms of reference counting, copy‑on‑write, and garbage collection that enable efficient memory management in the Zend engine.
zval Structure
The fundamental building block of PHP variables is the zval structure, which contains a zend_value union for the actual value or pointer, and two additional unions u1 and u2 that hold type information, flags, and auxiliary data.
Type Information (u1)
u1.typestores the variable's type, while type_flags is a mask used by the memory manager and garbage collector. Fields const_flags and reserved are present but not discussed here.
Auxiliary Data (u2)
u2provides extra space that can be used for purposes such as the next pointer in hash tables or fe_pos in foreach loops, aligning the whole zval to 16 bytes.
Value Types
For scalar types ( long, double) the value is stored directly; all other types store a pointer to a dedicated structure.
Scalar Types
True, false, null have no value field; long and double store their values directly in value.
String
Strings are represented by zend_string, which includes a reference count ( gc), a hash value ( h), length ( len), and the actual character data ( val). Different string categories exist (persistent, interned, permanent, constant) and are distinguished by flags in zval.u1.type_flag.
Array
PHP arrays are implemented as ordered hash tables. The internal layout is shown in the accompanying diagram.
Object/Resource
Objects and resources are flexible structures referenced via a pointer; their detailed layout is omitted.
Reference
References are created with the & operator, producing a new zval of type IS_REFERENCE whose val points to the original zval. References cannot be created by simple assignment.
Memory Management
PHP uses reference counting combined with copy‑on‑write (COW) to manage variable memory efficiently. When a variable is copied, the refcount of the underlying value is incremented instead of duplicating the data.
Reference Counting
The refcount field in a value’s gc structure tracks how many variables point to it. Increment on copy, decrement on destruction; when it reaches zero, the value is freed.
Copy‑On‑Write
If a value’s refcount is greater than one and a write occurs, PHP duplicates the value (separation) so that modifications affect only the writer.
$a = array(1, 2);
$b = &$a;
$c = $a; // separation occurs
$b[] = 3;Copyable Types
Only string and array types are marked as copyable via the IS_TYPE_COLLECTABLE flag; objects and resources are not.
#define IS_TYPE_COLLECTABLE (1<<3)Variable Recycling
Variables can be destroyed explicitly with unset or automatically when they go out of scope. The engine reduces the refcount and frees the value if it reaches zero.
Garbage Collection
When refcount remains > 0 after a variable is unset, the value may become garbage (e.g., circular references in arrays or objects). PHP places such values into a GC list and periodically scans them to reclaim memory.
Further details on the GC algorithm are omitted.
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.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
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.
