memory_get_usage
Returns the number of bytes of memory currently allocated to the running PHP script.
memory_get_usage(bool $real_usage = false): int- Added in PHP 4.3.2
Parameters
| Parameter | Type | Description |
|---|---|---|
$real_usageoptional | bool= false | Set to true to report the total memory the engine has requested from the system, including pages it holds but is not currently using. When false, only the memory actually handed out by the allocator is reported. |
Return value
intThe amount of memory currently allocated, in bytes.
memory_get_usage() reads the engine's own allocator counter, so it is cheap enough to call inside a loop. It is the standard way to find out what a chunk of code costs in RAM without attaching a profiler.
The two numbers it can give you
By default it reports memory the allocator has actually handed to your variables. Pass true and you get the larger figure: everything PHP has claimed from the operating system, rounded up to whole chunks. The memory_limit ini setting is enforced against the real figure, so if you are trying to predict how close you are to a fatal error, the true variant is the honest one. For measuring the cost of a data structure, the default is more useful because it does not jump in large steps.
How to measure something
Take a baseline, do the work, take a second reading, subtract. Anything else is noise. Remember that the value does not fall the moment you unset() a variable if something else still references it, and that the allocator normally keeps freed pages rather than returning them to the OS, so the real-usage figure tends to ratchet upward and rarely goes back down.
Example
When to use it
- Measure how many bytes a large array or parsed JSON document actually costs.
- Log memory consumption per batch in a long-running import so a leak shows up as a rising trend.
- Abort a queue worker gracefully once usage approaches memory_limit instead of dying with a fatal error.
Frequently asked questions
What is the difference between memory_get_usage() and memory_get_usage(true)?
Without the argument you get the memory the allocator has handed out to your variables; with true you get the total PHP has requested from the operating system, including chunks it is holding in reserve. The memory_limit setting is checked against the real figure, so use true when you care about how close you are to the limit.
Why does memory usage not go down after unset()?
unset() only removes one reference — if anything else still points at the value, nothing is freed. Even when the value is destroyed, PHP normally keeps the underlying pages for reuse, so the real-usage figure stays flat while the default reading drops.
Does memory_get_usage include memory used by extensions?
Only if the extension allocates through PHP's own emalloc allocator. Memory that an extension takes straight from the system with malloc, such as some image or database library buffers, is invisible to this function and to memory_limit.
More examples
Default reading versus real usage
The used figure climbs by roughly 4 MB and then drops back after unset(). The real figure climbs too but typically stays high afterwards, because the allocator keeps the pages it already obtained from the system rather than handing them back.
<?php
printf("used: %d bytes, real: %d bytes\n", memory_get_usage(), memory_get_usage(true));
$blob = str_repeat('x', 4 * 1024 * 1024);
printf("used: %d bytes, real: %d bytes\n", memory_get_usage(), memory_get_usage(true));
unset($blob);
printf("used: %d bytes, real: %d bytes\n", memory_get_usage(), memory_get_usage(true));Stop a worker before it hits memory_limit
The loop checks the real figure, the one memory_limit is actually enforced against, and exits cleanly at 80 percent instead of being killed mid-job by a fatal allocation error.
<?php
$limit = 1024 * 1024 * 16; // pretend the ini limit is 16 MB
$store = [];
for ($job = 1; $job <= 500; $job++) {
$store[] = str_repeat('payload', 20000);
if (memory_get_usage(true) > $limit * 0.8) {
echo "Stopping after {$job} jobs at 80% of the limit\n";
break;
}
}
printf("peak: %.1f MB\n", memory_get_peak_usage(true) / 1048576);Compare an array of objects with a generator
range() materialises every integer, so its cost scales with the count and lands in the megabytes. The generator holds one value at a time, so its footprint is a few hundred bytes regardless of how many items it will eventually yield.
<?php
$base = memory_get_usage();
$all = range(1, 200000);
$eager = memory_get_usage() - $base;
unset($all);
$base = memory_get_usage();
$lazy = (function () { for ($i = 1; $i <= 200000; $i++) { yield $i; } })();
$lazy->current();
$cost = memory_get_usage() - $base;
printf("range(): %d bytes\ngenerator: %d bytes\n", $eager, $cost);
Discussion