Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How much memory is PHP actually using?

Tags:

php

memory

I've noticed there's quite a difference between what top or ps reports as memory usage for a PHP process, compared to what the process itself thinks its using (with memory_get_usage).

How much memory is the process actually using?

When running the following code along with one of my apps:

echo "Memory usage: " . pretty_bytes(memory_get_usage()) . PHP_EOL;
echo "Peak memory usage: " . pretty_bytes(memory_get_peak_usage()) . PHP_EOL;
echo "'Actual' memory usage: " . pretty_bytes(memory_get_usage(true)) . PHP_EOL;
echo "'Actual' peak memory usage: " . pretty_bytes(memory_get_peak_usage(true)) . PHP_EOL;

$ps_output = exec("ps --pid " . getmypid() . " --no-headers -o rss");

echo "'Memory usage according to ps: " . pretty_bytes(intval($ps_output) * 1000);

The output at a random point was:

Memory usage: 4.77 MB
Peak memory usage: 4.99 MB
'Actual' memory usage: 5.00 MB
'Actual' peak memory usage: 5.00 MB
Memory usage according to ps: 17.66 MB

In my particular case, this is a concern because I'm running quite a few workers and daemons.

When I set the PHP memory limit to e.g. 128 MB for each of these daemons, the processes will only get killed once they reach 128 MB according to PHP's own measurements. However, according to ps, the processes will be using around 200 MB each by that time.

like image 513
Robbert Avatar asked Jul 28 '16 15:07

Robbert


2 Answers

It should be emphasized what exactly the values reported by ps and memory_get_usage(true) are.

ps -o rss reports the actual Resident Set Size. Relying on this value is quite a pitfall, as it does not include eventually swapped out memory. In general, you want the USS, the Unique Set Size, which is basically unshared memory (have a look at smem(8) for that). It is the amount of unshared memory the kernel actually has mapped pages for that process, i.e. physically present unshared memory in either RAM or swapfiles. This is as close as you can get for "real" memory usage. [Also refer to /proc/$PID/smaps for a detailed overview, as mentioned in the answer by IVO GELOV, where you could technically count the memory you want to count yourself by parsing that virtual file.]

Regarding memory_get_usage(), this reports the heap memory actually allocated by systems using PHP's internal memory manager. This means, libraries which directly use other memory managers of the system (mmap(2) or malloc(3)) do not expose their memory usage here. [This is for example why mysqlnd does show much memory usage while libmysqlclient does not - the latter uses malloc() internally.]

If you pass true as first parameter, i.e. memory_get_usage(true), it returns the total amount of memory PHP's internal memory manager has asked for from the system. This number in general is slightly, but not much higher than memory_get_usage(false). It also is the number which the memory_limit INI setting is compared against.

If you want to see how much workers you can run, note that PHP does not share much memory, except that the kernel may share the library memory and opcache, which shares the structures (opcodes, class info etc.). Thus the shared memory should rather not be important for you. The most important value for you thus should be the USS.

like image 81
bwoebi Avatar answered Oct 04 '22 20:10

bwoebi


memory_get_usage reports the memory allocated by a PHP process to run your script. ps reports memory used by the PHP process itself, which includes the memory used for your script. PHP process uses many external libraries, which all can allocate their memory without PHP process being aware of that.

So memory_get_usage and ps inherently measure different things and should report different numbers. It all comes down to how do you define "actual memory usage". I understand that in your case you are more interested in the memory usage of the PHP process. Then the output of ps is more relevant for you. But you can easily find out that even the RSS value reported by ps is not so black and white in the world of modern operating systems and shared memories.

See also:

  • http://php.net/manual/en/function.getrusage.php
  • How to measure actual memory usage of an application or process?
like image 39
Erki Aring Avatar answered Oct 04 '22 20:10

Erki Aring