views:

51

answers:

3

Hello!

I came across the PHP's memory_get_usage() and memory_get_peak_usage().

the problem is that I found that these two functions do not provide the real memory used by the current script. My test script is:

<?php

echo memory_get_usage();

echo '<br />';

$a = str_repeat('hello', 100000);

echo '<br />';

echo memory_get_usage();

echo '<br />';

echo memory_get_peak_usage();

?>

Which returns:

355120

5355216

5356008

What do you understand from this?

The first value is before executing the str_repeat() so it has to be the value of 0.

The second is after the process and it's OK to have a value greater than 0 but not that big value.

The third is the "peak" value and it's slightly greater than the second as I think it should be the biggest value in a processing microsecond.

So do you think that the real value of the current script's memory consumption should be like this:

memory_usage = the second memory usage - the first memory usage

peak_memory_usage = the third (peak_usage) - the first memory usage

which gives:

1) 5355216 - 355120 = 5000096 bytes

2) 5356008 - 355120 = 5000888 bytes

If this is how it works, I assume that the first 355120 bytes are the whole system allocated memory used by apache and other modules. as the first value never changes when you increase or decrease the number of repeats in the str_repeat(), only the two values after the process increase or decrease but never gets smaller that the first value.

+1  A: 

According to the php manual, memory_get_usage returns the amount of memory allocated to php, not necessarily the amount being used.

Sam Dufel
so do I have to subtract the first amount of memory allocated before the script from the the second amount of memory allocated after after executing the script? like the example I demonstrated in my question to get the real memory used to run the current script?
mohamed87
@mohamed87, No. That *is* the amount of memory your script is using. *The PHP interpreter uses memory, and therefore adds to the memory of your script*
Stargazer712
thanks for your replies. but the problem is that I want to monitor my php scripts' memory usage so that I don't get resources over consuming on a shared host.
mohamed87
@mohamed87, I can't explain it any clearer. *When looking at your memory usage, you __must__ look at the memory that is being used by the __interpreter__ as well*. Look at the big picture. The number being given to you by memory_get_usage() is the correct number.
Stargazer712
+1  A: 

Ok, your first assertion that the first memory_get_usage() should be 0 is wrong. According to PHP's documentation:

Returns the amount of memory, in bytes, that's currently being allocated to your PHP script.

Your script is running, therefore it must have some memory allocated to it. The first call informs you of how much that is.

Your second assertion that str_repeat() should not use that much memory is not looking at the whole picture.

You have the string "hello" (which uses 5 bytes) repeated 100,000 times, for a total of 500,000 bytes...minimum. The question is, how did PHP perform this action? Did they use code such as this? (pseudocode):

s = ""
for(i=0; i<100000; i++)
    s += "hello"

This code would require that you reallocate a new string for each iteration of the for loop. Now I can't pretend to say that I know how PHP implements str_repeat(), but you have to be extremely careful with how you use memory to keep memory usage down. From the appearance of things, they did not manage memory in that function as well as they could have.

Third, the difference between the peak memory usage and current memory usage likely comes from the stack that was necessary to make the function call to str_repeat(), as well as any local variables necessary within that function. The memory was probably reclaimed when the function returned.

Finally, Apache runs in a different process and we are dealing with virtual memory. Nothing that Apache does will affect the result of memory_get_usage() as processes do not "share" virtual memory.

Stargazer712
In my case with PHP 5.3.3 it gives the difference of almost exactly 500,000 as expected (see my answer in this thread)
mojuba
@majuba, indeed, it seems that there are enormous differences between different versions / compilations of PHP. Very interesting.
Stargazer712
+1  A: 

In my case (PHP 5.3.3 on Mac OS X 10.5) your script prints:

323964

824176

824980

Now, the difference between the second measurement and the first gives 500212, which is very close to the length of "hello" (5) times 100,000. So I would say no surprises here. The peak is a bit greater because of some temporary allocations when evaluating these statements.

(Your other questions are answered already)

mojuba
Very interesting. It seems like the PHP code in your implementation is much more efficient than that of the author of the question. Very very interesting...
Stargazer712