PHP memory consumption with Arrays and Objects update generators

PHP memory consumption with Arrays and Objects (update: generators)

Lessons learned:

  • objects need more memory than arrays (+ 2-10 percent)
  • comparing 32bit to 64bit systems, memory consumption increases by 100-230 percent
  • if array values are numeric, don’t save them as strings!
  • saving 1M integers takes 200M of memory with PHP on a 64bit plattform
    (increase by factor 25)
  • using SplFixedArray can reduce memory usage by 20-130 percent
  • avoid big Arrays and Objects in PHP whenever possible
    (don’t use file(‘big_file’) or explode(“\n”, file_get_contents(‘big_file’)), etc.)
  • use streams whenever possible (fopen, fsockopen, etc.)
  • use generators when available with PHP 5.5 (RFC)

More details and technical explanations about PHP’s memory usage can be found here

If you need to save memory temporarily in your script, you can stringify your array (increasing cpu usage and runtime):


$a = array();
for ($i=0; $i<1000000; $i++) {
$a[] = $i;
}
$a = implode(',', $a); // or $a = json_encode($a);

echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 8.0 M (64bit), 7.5 M (32bit)

Here is a small script to show how much memory PHP needs to handle bit Arrays:
(Tests made with PHP 5.3.10 and PHP 5.4.0)


ini_set('memory_limit', '1024M');

$a = '';
for ($i=0; $i<1000000; $i++) {
$a .= '1';
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 1.75 M (64bit), 1.25 M (32bit)


$a = array();
for ($i=0; $i<1000000; $i++) {
$a[$i] = true;
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 199.75 M (64bit), 80.75 M (32bit)

$a = new stdclass;
for ($i=0; $i<1000000; $i++) {
$a->$i = true;
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 207.50 M (64bit), 88.50 M (32bit)

$a = new SplFixedArray(1000000);
for ($i=0; $i<1000000; $i++) {
$a[$i] = true;
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 84.75 M (64bit), 34.75 M (32bit)


$a = array();
for ($i=0; $i<1000000; $i++) {
$a[$i] = $i;
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 199.75 M (64bit), 80.75 M (32bit)

$a = new stdclass;
for ($i=0; $i<1000000; $i++) {
$a->$i = $i;
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 207.50 M (64bit), 88.50 M (32bit)

$a = new SplFixedArray(1000000);
for ($i=0; $i<1000000; $i++) {
$a[$i] = $i;
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 84.75 M (64bit), 34,75 M (32bit)


$a = array();
for ($i=0; $i<1000000; $i++) {
$a[$i] = (string)$i;
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 322.00 M (64bit), 164.75 M (32bit)

$a = new stdclass();
for ($i=0; $i<1000000; $i++) {
$a->$i = (string)$i;
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 329.50 M (64bit), 172.50 M (32bit)

$a = new SplFixedArray(1000000);
for ($i=0; $i<1000000; $i++) {
$a[$i] = (string)$i;
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 207.00 M (64bit), 118.75 M (32bit)


$a = array();
for ($i=0; $i<1000000; $i++) {
$a[(string)$i] = (string)$i;
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 321.75 M (64bit), 164.75 M (32bit)


$a = array();
for ($i=0; $i<1000000; $i++) {
$a[$i] = "";
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 253.25 M (64bit), 96.00 M (32bit)

$a = new stdclass;
for ($i=0; $i<1000000; $i++) {
$a->$i = "";
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 261.00 M (64bit), 103.75 M (32bit)

$a = new SplFixedArray(1000000);
for ($i=0; $i<1000000; $i++) {
$a[$i] = "";
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 138.50 M (64bit), 50.25 M (32bit)



$a = array();
for ($i=0; $i<1000000; $i++) {
$a[$i] = "hello";
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 253.25 M (64bit), 96.00 M (32bit)

$a = new stdclass;
for ($i=0; $i<1000000; $i++) {
$a->$i = "hello";
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 261.00 M (64bit), 103.75 M (32bit)

$a = new SplFixedArray(1000000);
for ($i=0; $i<1000000; $i++) {
$a[$i] = "hello";
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 138.50 M (64bit), 50.25 M (32bit)


$a = array();
for ($i=0; $i<1000000; $i++) {
$a[$i] = array();
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 421.25 M (64bit), 126.50 M (32bit)

$a = new stdclass;
for ($i=0; $i<1000000; $i++) {
$a->$i = array();
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 428.75 M (64bit), 134.25 M (32bit)

$a = new SplFixedArray(1000000);
for ($i=0; $i<1000000; $i++) {
$a[$i] = array();
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 306.25 M (64bit), 50.75 M (32bit)


$a = array();
for ($i=0; $i<1000000; $i++) {
$a[$i] = array("");
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 665.25 M (64bit), 256.25 M (32bit)

$a = new stdclass;
for ($i=0; $i<1000000; $i++) {
$a->$i = array("");
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 673.00 M (64bit), 264.00 M (32bit)

$a = new SplFixedArray(1000000);
for ($i=0; $i<1000000; $i++) {
$a[$i] = array("");
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 550.50 M (64bit), 210.50 M (32bit)


$a = array();
for ($i=0; $i<1000000; $i++) {
$a[$i] = array("hello");
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 665.25 M (64bit), 256.25 M (32bit)

$a = new stdclass;
for ($i=0; $i<1000000; $i++) {
$a->$i = array("hello");
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 673.00 M (64bit), 264.00 M (32bit)

$a = new SplFixedArray(1000000);
for ($i=0; $i<1000000; $i++) {
$a[$i] = array("hello");
}
echo number_format(memory_get_usage(true)/1048576, 2)."\n";
// 550.50 M (64bit), 210.50 M (32bit)

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill the blank please: *