Php get memory size of variable

You can't retrospectively calculate the exact footprint of a variable as two variables can share the same allocated space in the memory

Let's try to share memory between two arrays, we see that allocating the second array costs half of the memory of the first one. When we unset the first one, nearly all the memory is still used by the second one.

echo memory_get_usage()."\n"; // <-- 433200
$c=range(1,100);
echo memory_get_usage()."\n"; // <-- 444348 (+11148)
$d=array_slice($c, 1);
echo memory_get_usage()."\n"; // <-- 451040 (+6692)
unset($c);
echo memory_get_usage()."\n"; // <-- 444232 (-6808)
unset($d);
echo memory_get_usage()."\n"; // <-- 433200 (-11032)

So we can't conclude than the second array uses half the memory, as it becomes false when we unset the first one.

For a full view about how the memory is allocated in PHP and for which use, I suggest you to read the following article: How big are PHP arrays (and values) really? (Hint: BIG!)

The Reference Counting Basics in the PHP documentation has also a lot of information about memory use, and references count to shared data segment.

The different solutions exposed here are good for approximations but none can handle the subtle management of PHP memory.

  1. calculating newly allocated space

If you want the newly allocated space after an assignment, then you have to use memory_get_usage() before and after the allocation, as using it with a copy does give you an erroneous view of the reality.

// open output buffer
echo "Result: ";
// call every function once
range(1,1); memory_get_usage();

echo memory_get_usage()."\n";
$c=range(1,100);
echo memory_get_usage()."\n";

Remember that if you want to store the result of the first memory_get_usage(), the variable has to already exist before, and memory_get_usage() has to be called another previous time, and every other function also.

If you want to echo like in the above example, your output buffer has to be already opened to avoid accounting memory needed to open the output buffer.

  1. calculating required space

If you want to rely on a function to calculate the required space to store a copy of a variable, the following code takes care of different optimizations:

Note that the size of the variable name matters in the memory allocated.

  1. Check your code!!

A variable has a basic size defined by the inner C structure used in the PHP source code. This size does not fluctuate in the case of numbers. For strings, it would add the length of the string.

typedef union _zvalue_value {
    long lval;                  /* long value */
    double dval;                /* double value */
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;              /* hash table value */
    zend_object_value obj;
} zvalue_value;

If we do not take the initialization of the variable name into account, we already know how much a variable uses (in case of numbers and strings):

44 bytes in the case of numbers

+ 24 bytes in the case of strings

+ the length of the string (including the final NUL character)

(those numbers can change depending on the PHP version)

You have to round up to a multiple of 4 bytes due to memory alignment. If the variable is in the global space (not inside a function), it will also allocate 64 more bytes.

So if you want to use one of the codes inside this page, you have to check that the result using some simple test cases (strings or numbers) match those data taking into account every one of the indications in this post ($_GLOBAL array, first function call, output buffer, ...)

(PHP 4 >= 4.3.2, PHP 5, PHP 7, PHP 8)

memory_get_usageReturns the amount of memory allocated to PHP

Description

memory_get_usage(bool $real_usage = false): int

Parameters

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()

Return Values

Returns the memory amount in bytes.

Examples

Example #1 A memory_get_usage() example

// 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"// 57960unset($a);

echo

memory_get_usage() . "\n"// 36744?>

See Also

  • memory_get_peak_usage() - Returns the peak of memory allocated by PHP
  • memory_limit

xelozz -at- gmail.com

12 years ago

To get the memory usage in KB or MB

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
?>

Alex Aulbach

11 years ago

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. :)

jeff dot peck at snet dot net

13 years ago

To get the memory usage in KB or MB

    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

"
"
;
    }
?>

stanislav dot eckert at vizson dot de

5 years ago

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):

// 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

randolphothegreat at yahoo dot com

17 years ago

[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:

$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.

lorin dot weilenmann at gmail dot com

11 years ago

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.

yousha dot a at hotmail dot com

4 years ago

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.

ad-rotator.com

18 years ago

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

miami at blackcrystal dot net

7 years ago

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.

    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.

    $a = ' ';
    do { 
$a .= $a . $a; }
    while (
getVirtualMemoryTaken() < 20 );
?>

e dot a dot schultz at gmail dot com

16 years ago

This is a function that should work for both Windows XP/2003 and most distrabutions of UNIX and Mac OS X.

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;
        }
    }
}
?>

vesa dot kivisto at nepton dot fi

17 years ago

[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!

// 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 'no value';

  }

?>

MagicalTux at FF dot st

17 years ago

When you need to get the OS, do not use $_SERVER['OS'] or $_ENV['OS'], better use PHP_OS constant !
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")

guenter_doege at web dot de

17 years ago

The Win XP / 2003 workaround script will also work with windows 2000 with a few slight modifications.

Please note that you'll need the pslist.exe utility from http://www.sysinternals.com/Utilities/PsTools.html because win/2000 itself does not provide a task list utility.

function getMemUsage()
{

            if (

function_exists('memory_get_usage'))
       {
           return
memory_get_usage();
       }
       else if (
substr(PHP_OS,0,3) == 'WIN')
       {
          
// Windows 2000 workaround$output = array();
          
exec('pslist ' . getmypid() , $output);
           return
trim(substr($output[8],38,10));
       }
       else
       {
           return
'no value';
       }
}
?>

joe at schmoe dot com

15 years ago

the various memory_get_usage replacements here don't seem to work on Mac OS X 10.4(Intel)

I got it to work like this...

function memory_get_usage()
{
    
$pid = getmypid();
    
exec("ps -o rss -p $pid", $output);
     return
$output[1] *1024;
}
?>

miteigi nemoto (miteigi at yandex dot ru)

13 years ago

Decision a memory_get_usage problem for windows system

Tested OS: Windows XP
Server: Apache

PHP must be loaded as CGI to get correctly memory usage by Process ID ( getmypid() ) and with cmd-tools like tasklist.exe

PHP as CGI have your own PID instead constant Apache PID and you get a true memory size independed form Apache memory usage.

Configure in httpd.conf of Apache:

1. Comment the line like this:
LoadModule php4_module "/usr/local/php/sapi/php4apache.dll"
or
LoadModule php5_module "/usr/local/php5/php5apache.dll"

2. Add this and edit your path to php:

  Options ExecCGI

ScriptAlias "/__php_dir__/" "z:/usr/local/php/"
Action application/x-httpd-php "/__php_dir__/php.exe"

3. Restart Apache

Use this PHP-code:

/**
* A memory_get_usage() for Windows System, wich compiled without --enable-memory-limit
* PHP must be loaded as CGI
* Greetings form miteigi nemoto
* @return string
*/
function memory_get_usage_by_tasklist()
{
   
$output = array();
   
exec( 'tasklist ', $output );
    foreach (
$output as $value)
    {
       
$ex=explode(" ",$value);
       
$count_ex=count($ex);
        if (
eregi(" ".getmypid()." Console",$value))
        {
           
$memory_size=$ex[$count_ex-2]." Kb";
            return
$memory_size;
        }
    }
}
echo
memory_get_usage_by_tasklist();
?>

How to get memory usage in PHP?

The memory_get_usage function can be used to track the memory usage. The 'malloc' function is not used for every block required, instead a big chunk of system memory is allocated and the environment variable is changed and managed internally. The above mentioned memory usage can be tracked using memory_get_usage().

How to check PHP memory?

How to check your usage of PHP script memory script.
memory_get_usage() Although this function gives back the amount of memory allotted to a PHP script, you will see the amount in bytes. ... .
memory_get_usage/1024. If you want to convert this amount to MB, use:.
memory_get_usage/1048576. ... .
memory_get_peak_usage() ... .
$real_usage..

Which function is used to detect how much memory the variable uses?

Is there a function in PHP (or a PHP extension) to find out how much memory a given variable uses? sizeof just tells me the number of elements/properties. memory_get_usage helps in that it gives me the memory size used by the whole script.

How much memory does each PHP process consume?

The default memory limit of 128 MB in PHP is a conservative default intended to give enough “breathing room” for virtually any kind of application. It is likely that your code does not consume that much memory during a request, so lowering the limit is a great way of optimizing your application performance.