2

I think I've read all topics on stackoverflow.com about memory_get_usage() and memory_peak_get_usage() functions, but it appears that the explanations won't fit my case.

My script showed the following result:

memory peak usage (true): 2
memory peak usage (false): 0.44921112060547
memory get usage: 0.40422821044922

memory peak usage (true): 2
memory peak usage (false): 6.5214996337891
memory get usage: 1.2414016723633

memory peak usage (true): 2
memory peak usage (false): 6.5214996337891
memory get usage: 1.2413940429688

memory peak usage (true): 2
memory peak usage (false): 6.5214996337891
memory get usage: 1.2425689697266

memory peak usage (true): 2
memory peak usage (false): 6.5214996337891
memory get usage: 1.2467498779297

memory peak usage (true): 2
memory peak usage (false): 18.253067016602
memory get usage: 2.5322036743164

memory peak usage (true): 2
memory peak usage (false): 18.253067016602
memory get usage: 2.5322113037109

memory peak usage (true): 2
memory peak usage (false): 18.253067016602
memory get usage: 2.406005859375

The logs are generated by following commands, repeated sometimes through the code:

echo 'memory peak usage (true): '.(memory_get_peak_usage(true)/1024/1024).'<br>';
echo 'memory peak usage (false): '.(memory_get_peak_usage(false)/1024/1024).'<br>';
echo 'memory get usage: '.(memory_get_usage()/1024/1024).'<br><br>';

Info: For the last log i had set some variables to null and i think they are freed by garbage collector and because that the memory get usage lowered to 2.40 from 2.53.

My question is: WTH is happening? Why memory_get_usage() is larger than memory_get_peak_usage(true)? And why memory_get_peak_usage(false) is larger than memory_get_peak_usage(true)?

Its totally different from this thread: memory_get_peak_usage() with "real usage"

Bielcito
  • 83
  • 8

1 Answers1

1

First of all, there's this page http://jpauli.github.io/2014/07/02/php-memory.html, which explains in detail how PHP allocates memory, and how ZendMM works. I highly recommend you check it out if you're willing to dwell in low-level PHP programming.

Now, moving on to your question, let me tell you: Nowhere in the Internet did i find a satisfactory answer. That being said, what follows is a result of fair assumptions based on documentation and other sources of information.


as stated in PHP's documentation, memory_get_usage (which defaults the $real_usage to false) returns the amount of memory currently being allocated to your script. It also only tracks memory allocated by using emalloc().

Let's give out some definitions before moving further:

  • memory_get_usage (false) - Returns the sum of bytes requested by calls to emalloc + header bytes + memory alignment. It's not perfect as it doesn't take in account the amount of blocks wasted by not being able to fit space in the remaining segments of the allocated blocks.

  • memory_get_peak_usage(false) - Returns the peak of memory that has been allocated to your script. Same as the case above, it might give lower results than the actual amount of bytes used.

  • memory_get_peak_usage(true) - Returns the actual peak of bytes allocated by the script.


"Why memory_get_usage() is larger than memory_get_peak_usage(true)?"

It's most likely happening because they're using different ways of calculating the memory usage. - Peak usage (true) is trying to tell you the amount of actual bytes your script reached, while get_usage(false) only tells you the amount the sum of all emalloc calls. It might be higher simply because it's not programmed to realize your program is currently freeing memory, and that said 2.5 bytes of data may have actually fit in 2 bytes of your actual memory the entire time, due to constant freeing and allocating. That's based on the commentary made in the page i linked above:

memory_get_usage() give an average information, often accurate, but not 100% accurate on a byte-basis

Meaning it attempts to tell you the average of amount it believes' being allocated by calculating emallocs, but it can't know how many memory blocks your script is spending as long as it's set to false.

Why memory_get_peak_usage(false) is larger than Memory_get_peak_usage(true)?"

Here's the part where it gets weird. I've honestly never seen that before, and do believe that's most likely a misunderstanding. This may be a result of your script allocating memory in a way the (false) implementation believes memory's still allocated to that resource, when in fact, (true) assures the most your script's used were 2 bytes.

I have no hardcore experience with PHP, and tried to answer this by googling a lot. I hope it gives you some insight on what's going on.

In any case, try not to bash your keyboard in anger even though it doesn't make perfect sense. The "false" implementation of these methods are highly erratic, and shouldn't be used to compare with their "true" counterparts. Worst case scenario, it's just poor implementation on PHP's part.

Good luck on your PHP adventures!

Update

This didn't help me at all, but i did find the source codes for both functions at:

Here goes:

ZEND_API size_t zend_memory_usage(int real_usage)
{
#if ZEND_MM_STAT
    if (real_usage) {
        return AG(mm_heap)->real_size;
    } else {
        size_t usage = AG(mm_heap)->size;
        return usage;
    }
#endif
    return 0;
}

ZEND_API size_t zend_memory_peak_usage(int real_usage)
{
#if ZEND_MM_STAT
    if (real_usage) {
        return AG(mm_heap)->real_peak;
    } else {
        return AG(mm_heap)->peak;
    }
#endif
    return 0;
}

References:

memory_get_peak_usage documentation

memory_get_usage documentation

Perfect script for calculating memory usage