To get the memory usage in KB or MB
<?php
function convert($size)
{
$unit=array('b','kb','mb','gb','tb','pb');
return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
echo convert(memory_get_usage(true)); // 123 kb
?>
(PHP 4 >= 4.3.2, PHP 5, PHP 7, PHP 8)
memory_get_usage — Returns the amount of memory allocated to PHP
Returns the amount of memory, in bytes, that's currently being allocated to your PHP script.
real_usage
Set this to true
to get total memory allocated from
system, including unused pages.
If not set or false
only the used memory is reported.
Note:
PHP does not track memory that is not allocated by
emalloc()
Returns the memory amount in bytes.
Example #1 A memory_get_usage() example
<?php
// This is only an example, the numbers below will
// differ depending on your system
echo memory_get_usage() . "\n"; // 36640
$a = str_repeat("Hello", 4242);
echo memory_get_usage() . "\n"; // 57960
unset($a);
echo memory_get_usage() . "\n"; // 36744
?>
To get the memory usage in KB or MB
<?php
function convert($size)
{
$unit=array('b','kb','mb','gb','tb','pb');
return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
echo convert(memory_get_usage(true)); // 123 kb
?>
Note, that the official IEC-prefix for kilobyte, megabyte and so on are KiB, MiB, TiB and so on.
See http://en.wikipedia.org/wiki/Tebibyte
At first glance this may sound like "What the hell? Everybody knows, that we mean 1024 not 1000 and the difference is not too big, so what?". But in about 10 years, the size of harddisks (and files on them) reaches the petabyte-limit and then the difference between PB and PiB is magnificent.
Better to get used to it now. :)
memory_get_usage() is used to retrieve the memory allocated to PHP only (or your running script). But intuitively, many people expect to get the memory usage of the system, based on the name of the function.
So if you need the overall memory usage, following function might be helpful. If retrieves the memory usage either in percent (without the percent sign) or in bytes by returning an array with free and overall memory of your system. Tested with Windows (7) and Linux (on an Raspberry Pi 2):
<?php
// Returns used memory (either in percent (without percent sign) or free and overall in bytes)
function getServerMemoryUsage($getPercentage=true)
{
$memoryTotal = null;
$memoryFree = null;
if (stristr(PHP_OS, "win")) {
// Get total physical memory (this is in bytes)
$cmd = "wmic ComputerSystem get TotalPhysicalMemory";
@exec($cmd, $outputTotalPhysicalMemory);
// Get free physical memory (this is in kibibytes!)
$cmd = "wmic OS get FreePhysicalMemory";
@exec($cmd, $outputFreePhysicalMemory);
if ($outputTotalPhysicalMemory && $outputFreePhysicalMemory) {
// Find total value
foreach ($outputTotalPhysicalMemory as $line) {
if ($line && preg_match("/^[0-9]+\$/", $line)) {
$memoryTotal = $line;
break;
}
}
// Find free value
foreach ($outputFreePhysicalMemory as $line) {
if ($line && preg_match("/^[0-9]+\$/", $line)) {
$memoryFree = $line;
$memoryFree *= 1024; // convert from kibibytes to bytes
break;
}
}
}
}
else
{
if (is_readable("/proc/meminfo"))
{
$stats = @file_get_contents("/proc/meminfo");
if ($stats !== false) {
// Separate lines
$stats = str_replace(array("\r\n", "\n\r", "\r"), "\n", $stats);
$stats = explode("\n", $stats);
// Separate values and find correct lines for total and free mem
foreach ($stats as $statLine) {
$statLineData = explode(":", trim($statLine));
//
// Extract size (TODO: It seems that (at least) the two values for total and free memory have the unit "kB" always. Is this correct?
//
// Total memory
if (count($statLineData) == 2 && trim($statLineData[0]) == "MemTotal") {
$memoryTotal = trim($statLineData[1]);
$memoryTotal = explode(" ", $memoryTotal);
$memoryTotal = $memoryTotal[0];
$memoryTotal *= 1024; // convert from kibibytes to bytes
}
// Free memory
if (count($statLineData) == 2 && trim($statLineData[0]) == "MemFree") {
$memoryFree = trim($statLineData[1]);
$memoryFree = explode(" ", $memoryFree);
$memoryFree = $memoryFree[0];
$memoryFree *= 1024; // convert from kibibytes to bytes
}
}
}
}
}
if (is_null($memoryTotal) || is_null($memoryFree)) {
return null;
} else {
if ($getPercentage) {
return (100 - ($memoryFree * 100 / $memoryTotal));
} else {
return array(
"total" => $memoryTotal,
"free" => $memoryFree,
);
}
}
}
function getNiceFileSize($bytes, $binaryPrefix=true) {
if ($binaryPrefix) {
$unit=array('B','KiB','MiB','GiB','TiB','PiB');
if ($bytes==0) return '0 ' . $unit[0];
return @round($bytes/pow(1024,($i=floor(log($bytes,1024)))),2) .' '. (isset($unit[$i]) ? $unit[$i] : 'B');
} else {
$unit=array('B','KB','MB','GB','TB','PB');
if ($bytes==0) return '0 ' . $unit[0];
return @round($bytes/pow(1000,($i=floor(log($bytes,1000)))),2) .' '. (isset($unit[$i]) ? $unit[$i] : 'B');
}
}
// Memory usage: 4.55 GiB / 23.91 GiB (19.013557664178%)
$memUsage = getServerMemoryUsage(false);
echo sprintf("Memory usage: %s / %s (%s%%)",
getNiceFileSize($memUsage["total"] - $memUsage["free"]),
getNiceFileSize($memUsage["total"]),
getServerMemoryUsage(true)
);
?>
The function getNiceFileSize() is not required. Just used to shorten size in bytes.
Note: If you need the server load (CPU usage), I wrote a nice function to get that too: http://php.net/manual/en/function.sys-getloadavg.php#118673
To get the memory usage in KB or MB
<?php
function echo_memory_usage() {
$mem_usage = memory_get_usage(true);
if ($mem_usage < 1024)
echo $mem_usage." bytes";
elseif ($mem_usage < 1048576)
echo round($mem_usage/1024,2)." kilobytes";
else
echo round($mem_usage/1048576,2)." megabytes";
echo "<br/>";
}
?>
I can confirm that this function triggers a garbage collection. I have a script that exceeded 128MB of memory at some point and ended with a fatal error. I was confused, because the script dealt with some large files initially, but the memory load from that point on should have been marginal, and the error occurred at the very end.
Those large files were dealt in a dedicated function and i even used unset() on the variable holding the file after the file was written to disk inside that function. So the memory should have been cleared twice, first after the unset() call, and second once the function ended.
To debug the memory usage, I called memory_get_usage(true) at some points and echo-ed the memory allocation. Just by adding a few echos here and there in the script, the memory usage never exceeded 1MB overhead (on top of the current file size) and the memory error disappeared.
[EDIT by danbrown AT php DOT net: This is intended by the author to only be used with PHP 4 < 4.3.2.]
I'd just like to point out that although sandeepc at myrealbox dot com's idea for displaying the current memory usage is a good one, it's perhaps a bad idea to pipe the entire process list through grep. A better performing method would be to select only the process we're interested in:
<?php
$pid = getmypid();
error_log('MEMORY USAGE (% KB PID ): ' . `ps --pid $pid --no-headers -o%mem,rss,pid`);
?>
True, it's not much of a performance boost, but every bit helps.
Note that the description for `memory_get_usage` is different than it's default parameter!
"`int memory_get_usage ([ bool $real_usage = FALSE ] )`
Returns the amount of memory, in bytes, that's currently being allocated to your PHP script. "
Default parameter = `FALSE`
WRONG description: Returns the amount of memory, in bytes, that's currently being allocated to your PHP script.
It must be: Returns the amount of memory, in bytes, that's currently used by your PHP script.
The method sandeepc at myrealbox dot com posted yields larger memory usage, my guess is that it includes all the PHP interpreter/internal code and not just the script being run.
1) Use ps command
MEMORY USAGE (% KB PID ): 0.8 12588 25087 -> about 12MB
2) Use memory_get_usage()
int(6041952) -> about 6MB
Sometimes, we need all memory to run our task, we do ini_set('memory_limit', -1 ), or maximum value we have.
To avoid stuck of server on long and memory consuming tasks, i wrote this check. This is not the same as memory_get_usage() do, but more. It shows virtual memory amount, taken by your process. In percents.
<?php
function getVirtualMemoryTaken()
{
$pid = getmypid();
$a = `ps -p $pid v | awk 'END{print $9}'`;
return $a*1;
}
?>
It works only in linux, tested in Ubuntu 14.
<?php
$a = ' ';
do { $a .= $a . $a; }
while (getVirtualMemoryTaken() < 20 );
?>
[EDIT by danbrown AT php DOT net: This function will only extend Windows versions of PHP where the server has the required third-party software.]
I was unable to get the previous examples working properly and created code which works at least for me. Enjoy!
<?php
// Please note that you'll need the pslist.exe utility from http://www.sysinternals.com/Utilities/PsTools.html
// This is because win/2000 itself does not provide a task list utility.
//
function getMemoryUsage() {
// try to use PHP build in function
if( function_exists('memory_get_usage') ) {
return memory_get_usage();
}
// Try to get Windows memory usage via pslist command
if ( substr(PHP_OS,0,3) == 'WIN') {
$resultRow = 8;
$resultRowItemStartPosition = 34;
$resultRowItemLength = 8;
$output = array();
exec('pslist -m ' . getmypid() , $output);
return trim(substr($output[$resultRow], $resultRowItemStartPosition, $resultRowItemLength)) . ' KB';
}
// No memory functionality available at all
return '<b style="color: red;">no value</b>';
}
?>
This is a function that should work for both Windows XP/2003 and most distrabutions of UNIX and Mac OS X.
<?php
if( !function_exists('memory_get_usage') )
{
function memory_get_usage()
{
//If its Windows
//Tested on Win XP Pro SP2. Should work on Win 2003 Server too
//Doesn't work for 2000
//If you need it to work for 2000 look at http://us2.php.net/manual/en/function.memory-get-usage.php#54642
if ( substr(PHP_OS,0,3) == 'WIN')
{
if ( substr( PHP_OS, 0, 3 ) == 'WIN' )
{
$output = array();
exec( 'tasklist /FI "PID eq ' . getmypid() . '" /FO LIST', $output );
return preg_replace( '/[\D]/', '', $output[5] ) * 1024;
}
}else
{
//We now assume the OS is UNIX
//Tested on Mac OS X 10.4.6 and Linux Red Hat Enterprise 4
//This should work on most UNIX systems
$pid = getmypid();
exec("ps -eo%mem,rss,pid | grep $pid", $output);
$output = explode(" ", $output[0]);
//rss is given in 1024 byte units
return $output[1] * 1024;
}
}
}
?>
When you need to get the OS, do not use $_SERVER['OS'] or $_ENV['OS'], better use PHP_OS constant !
<?php
if (substr(PHP_OS,0,3)=='WIN') {
// [...]
}
?>
You also have other values such as CYGWIN_NT-5.0, Linux, ... this is the best way to get system's os (anyone on linux can do an "export OS=windows")