views:

231

answers:

4

I'm making a little benchmark class to display page load time and memory usage. Load time is already working, but when I display the memory usage, it doesn't change Example:

$conns = array();
ob_start();
benchmark::start();
$conns[] = mysql_connect('localhost', 'root', '');
benchmark::stop();
ob_flush();

uses the same memory as

$conns = array();
ob_start();
benchmark::start();
for($i = 0; $i < 1000; $i++)
{
   $conns[] = mysql_connect('localhost', 'root', '');
}
benchmark::stop();
ob_flush();

I'm using memory_get_usage(true) to get the memory usage in bytes.

+2  A: 

I'm no Guru in PHP's internals, but I could imagine an echo does not affect the amount of memory used by PHP, as it just outputs something to the client.

It could be different if you enable output buffering.

The following should make a difference:

$result = null;
benchmark::start()
for($i = 0; $i < 10000; $i++)
{
   $result.='test';
}
Pekka
I have done a bit of investigatiopn about memory management in PHP, and yest, it does change over time. Adding simple variables seems to cause the memory to increase in steps (pre-allocation?). To see big jumps, compare before and after includes.
symcbean
A: 

echo won't change the allocated number of bytes (unless you use output buffers).

the $i-variable is being unset after the for-loop, so it's not changing the number of allocated bytes either.

try to use a output buffering example:

ob_start();
benchmark::start();
for($i = 0; $i < 10000; $i++)
{
   echo 'test';
}
benchmark::stop();
ob_flush();
henchman
ob_start();benchmark::start();for($i = 0; $i < 100; $i++){ $conns[] = mysql_connect('localhost', 'root', '');}benchmark::stop();ob_flush();I still get the same memory usage ...
Qtacz
+2  A: 

memory_get_usage(true) will show the amount of memory allocated by the php engine, not actually used by the script. It's very possible that your test script hasn't required the engine to ask for more memory.

For a test, grab a large(ish) file and read it into memory. You should see a change then.

I've successfully used memory_get_usage(true) to track the memory usage of web crawling scripts, and it's worked fine (since the goal was to slow things down before hitting the system memory limit). The one thing to remember is that it doesn't change based on actual usage, it changes based on the memory requested by the engine. So what you end up seeing is sudden jumps instead of slowing growing (or shrinking).

If you set the real_usage flag to false, you may be able to see very small memory changes - however, this won't help you monitor the true amount of memory php is requesting from the system.

(Update: To be clear the difference I describe is between memory used by the variables of your script, compared to the memory the engine requested to run your script. All the same script, different way of measuring.)

Tim Lytle
i disagree. the docs say "Returns the amount of memory, in bytes, that's currently being allocated to your PHP **script**. "
henchman
@henchman, you're missing the point, sure it's all the same script, but without real_usage set to true it reports the memory used by your 'code', with real_usage set to true it reports the memory PHP requested from the system to run your 'code'.
Tim Lytle
@henchman My quote from the docs: "Set this to TRUE to get the real size of memory **allocated from system**. If not set or FALSE only the **memory used** by emalloc() is reported." :-)
Tim Lytle
+1  A: 

Look at:

for($i = 0; $i < 1000; $i++)
{
   $conns[] = mysql_connect('localhost', 'root', '');
}

You could have looped to 100,000 and nothing would have changed, its the same connection. No resources are allocated for it because the linked list remembering them never grew. Why would it grow? There's already (assumingly) a valid handle at $conns[0]. It won't make a difference in memory_get_usage(). You did test $conns[15] to see if it worked, yes?

Can root@localhost have multiple passwords? No. Why would PHP bother to handle another connection just because you told it to? (tongue in cheek).

I suggest running the same thing via CLI through Valgrind to see the actual heap usage:

valgrind /usr/bin/php -f foo.php .. or something similar. At the bottom, you'll see what was allocated, what was freed and garbage collection at work.

Disclaimer: I do know my way around PHP internals, but I am no expert in that deliberately obfuscated maze written in C that Zend calls PHP.

Tim Post