Backend Development 9 min read

Understanding PHP unset(): Does It Really Release Memory?

This article examines whether PHP's unset() function truly frees memory by debunking common myths, demonstrating verification methods, analyzing the Zend engine's memory manager, and presenting practical code examples that reveal how different variable types affect memory usage after unsetting.

360 Tech Engineering
360 Tech Engineering
360 Tech Engineering
Understanding PHP unset(): Does It Really Release Memory?

PHP provides the unset() construct for releasing variables, but it is not a regular function and its impact on memory is often misunderstood. The article begins by listing common misconceptions about unset() , such as it not actually freeing memory or only working for variables larger than 256 bytes.

Two verification methods are shown. The first checks if unset exists as a function:

$ php -r "var_dump(function_exists('unset'));"
bool(false)

The second attempts to reflect the function definition:

$ php --rf unset
Exception: Function unset() does not exist

These checks are not sufficient because unset is a language construct, not a callable function. The article then explores the Zend language scanner to show that unset is defined as a token ( T_UNSET ) in the source.

It explains the difference between language constructs and functions, quoting the PHP manual that unset cannot be called via variable functions.

The memory_get_usage() function is introduced, with its prototype and the meaning of the $real_usage flag. The article describes how the Zend Memory Manager (ZMM) allocates memory in pools and how memory_get_usage() reports used memory.

Several code examples demonstrate memory behavior:

<?php
var_dump(memory_get_usage());
$user = 'fanjiapeng';
var_dump(memory_get_usage());
unset($user);
var_dump(memory_get_usage());

Running this script shows that memory usage does not decrease after unsetting a small string because the variable is stored in the interned strings table, which is not freed by unset() .

A second example concatenates the current time to the string, creating a temporary string (IS_TMP_VAR). After unsetting, memory usage drops, illustrating that unset() can free temporary strings that are managed by ZMM.

<?php
var_dump(memory_get_usage());
$user = 'fanjiapeng' . time();
var_dump(memory_get_usage());
unset($user);
var_dump(memory_get_usage());

A third example loads a large file into a variable (IS_VAR) and then unsets it. Because the variable exceeds the 2 MB threshold, it is allocated as a huge block via zend_mm_alloc_huge() and released with munmap() , causing a noticeable drop in memory usage.

<?php
var_dump(memory_get_usage(true));
$user = file_get_contents('/tmp/big_string.log'); // ~7.8 MB
var_dump(memory_get_usage(true));
unset($user);
var_dump(memory_get_usage(true));

The article summarizes that when ZMM is enabled, unset() returns small and medium allocations to ZMM but does not return them to the operating system, while huge allocations are released back to the OS. If ZMM is disabled, PHP falls back to malloc() / free() , and unset() interacts directly with system memory, which may be less efficient.

In conclusion, unset() does free memory for certain variable types, but the freed memory is usually returned to the Zend memory manager rather than the OS, and interned strings are never released by unset() .

backendperformancememory managementphpunsetzend
360 Tech Engineering
Written by

360 Tech Engineering

Official tech channel of 360, building the most professional technology aggregation platform for the brand.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.