PHP实际使用了多少内存?

PHP实际使用了多少内存?,php,memory,Php,Memory,我注意到,PHP进程的top或ps所报告的内存使用情况与进程本身所认为的(使用memory\u get\u usage)有很大的不同 进程实际使用了多少内存 将以下代码与我的某个应用程序一起运行时: echo "Memory usage: " . pretty_bytes(memory_get_usage()) . PHP_EOL; echo "Peak memory usage: " . pretty_bytes(memory_get_peak_usage()) . PHP_EOL; echo

我注意到,PHP进程的
top
ps
所报告的内存使用情况与进程本身所认为的(使用
memory\u get\u usage
)有很大的不同

进程实际使用了多少内存

将以下代码与我的某个应用程序一起运行时:

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);
随机点的输出为:

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
在我的特殊情况下,这是一个值得关注的问题,因为我正在运行相当多的worker和守护进程


当我将每个守护进程的PHP内存限制设置为128 MB时,根据PHP自己的度量,只有当进程达到128 MB时,进程才会被杀死。但是,根据
ps
,到那时,每个进程将使用大约200 MB的内存。

内存使用情况报告PHP进程为运行脚本分配的内存
ps
报告PHP进程本身使用的内存,其中包括用于脚本的内存。PHP进程使用许多外部库,这些库都可以在PHP进程不知道的情况下分配内存

所以
memory\u get\u usage
ps
本质上衡量不同的事物,应该报告不同的数字。这一切都归结到如何定义“实际内存使用”。我知道在你的例子中,你对PHP进程的内存使用更感兴趣。那么
ps
的输出对您来说就更相关了。但是你可以很容易地发现,在现代操作系统和共享内存的世界中,即使是
ps
报告的RSS值也不是那么黑白分明

另见:


发出以下命令之一时,您可能会发现有趣的事情:

cat /proc/PID_NUMBER/smaps
pmap -d PID_NUMBER

应该强调的是
ps
memory\u get\u usage(true)
报告的值到底是什么

ps-o rss
报告实际驻留集大小。依赖这个值是一个很大的陷阱,因为它不包括最终交换的内存。通常,您需要USS,即唯一的设置大小,它基本上是非共享内存(请查看
smem(8)
)。它是内核实际为该进程映射页面的非共享内存量,即在RAM或交换文件中物理呈现非共享内存。这是“真实”内存使用情况下所能达到的最大值。[另请参阅
/proc/$PID/smaps
了解详细概述,如IVO GELOV在回答中所述,您可以通过解析该虚拟文件,从技术上计算您想要计算的内存。]

关于
memory\u get\u usage()
,它报告了使用PHP内部内存管理器的系统实际分配的堆内存。这意味着,直接使用系统其他内存管理器的库(
mmap(2)
malloc(3)
)不会在此处公开它们的内存使用情况。[这就是为什么mysqlnd显示了大量内存使用,而libmysqlclient没有显示的原因-后者在内部使用
malloc()
。]

如果将
true
作为第一个参数传递,即
memory\u get\u usage(true)
,它将返回PHP的内部内存管理器向系统请求的内存总量。这个数字通常略高于
内存使用率(false)
。它也是比较
内存限制
INI设置的数字


如果您想知道可以运行多少worker,请注意PHP不共享多少内存,除了内核可能共享库内存和opcache,后者共享结构(操作码、类信息等)。因此,共享内存对您来说并不重要。因此,对你来说最重要的价值应该是USS。

一些没有解释的秘密结果(尽管可能具有教育意义)可能不是正确的方法;o) 很可能是这样,但除非你链接到这些地方中的某些地方,否则你的答案本身并不能提供任何见解。抱歉-超时5分钟:(,,,,虽然不是最详细的答案,但事实证明,这确实有助于找出内存使用的来源。我们能够从这些命令中确定,至少我们正在使用的PHP模块没有内存泄漏。谢谢Ivo。谢谢Erki。这是一个很有帮助的开始,但我们仍然缺少一些级别的d详细说明@bwoebi能够在他的回答中提供。谢谢@bwoebi。这和Ivo的回答让我们对问题有了足够的了解,可以解决手头的问题。