了解memory_get_usage()和pmap

时间:2013-02-14 14:29:58

标签: php pmap

我正在尝试了解一些php进程的内存使用情况。我已尝试同时使用get_memory_usage()pmap,但结果似乎相差一个数量级。我已尝试同时使用memory_get_usage()memory_get_usage(true)以及memory_get_peak_usage(true),但即使使用memory_get_peak_usage(true)(所有三个品种中最大的一个),仍然存在巨大的问题通过pmap报告。

更具体地说,在我的php脚本中每分钟调用memory_get_peak_usage(true)会返回1.75MB到3.5MB之间的值,而pmap -d PID的典型结果会给出类似的结果:

...

b7839000       4 r---- 0000000000008000 0ca:00060 libcrypt-2.11.1.so
b783a000       4 rw--- 0000000000009000 0ca:00060 libcrypt-2.11.1.so
b783b000     156 rw--- 0000000000000000 000:00000   [ anon ]
b7864000       8 rw--- 0000000000000000 000:00000   [ anon ]
b7867000      12 r-x-- 0000000000000000 0ca:00060 libgpg-error.so.0.4.0
b786a000       4 r---- 0000000000002000 0ca:00060 libgpg-error.so.0.4.0
b786b000       4 rw--- 0000000000003000 0ca:00060 libgpg-error.so.0.4.0
b786c000       4 r---- 0000000000000000 000:00000   [ anon ]
b786d000      16 rw--- 0000000000000000 000:00000   [ anon ]
b7871000     108 r-x-- 0000000000000000 0ca:00060 ld-2.11.1.so
b788c000       4 r---- 000000000001a000 0ca:00060 ld-2.11.1.so
b788d000       4 rw--- 000000000001b000 0ca:00060 ld-2.11.1.so
bffc7000     136 rw--- 0000000000000000 000:00000   [ stack ]
f57fe000       4 r-x-- 0000000000000000 000:00000   [ anon ]
mapped: 32740K    writeable/private: 13116K    shared: 28K

如果我理解正确,可写/私有数字是最相关的数字,因为它是该进程专用的内存。将近13MB与memory_get_peak_usage(true)报告的数量相差甚远。有人可以解释这个差异吗?

2 个答案:

答案 0 :(得分:3)

我的理解是memory_get_peak_usage()将返回脚本使用的内存量。所以这不包括PHP的开销。

  

返回已分配给PHP脚本的内存峰值(以字节为单位)。

您可以通过编译更少的扩展来减少PHP使用的内存。

PHP本身是一个大型应用程序,尤其是默认扩展。我们(作为php开发人员)可以编写像simplexml_load_string()这样的简单代码并观察魔法的发生,但是启发魔法的代码在内存中的某个地方徘徊。查看phpinfo()的输出将显示安装了多少扩展。 PHP内部代码将使用PHP并将其转换为OPCODE,然后执行这些操作码的代码。每个PHP实例都会执行它。

这种内存使用显然是非平凡的,但可以预料。如果你必须编写所有代码来处理传入的GET / POST / FILES管理XML,文件和流魔术等。内存使用会很快加起来。

因此,常见的性能技术是删除所有不需要的扩展以缩小可执行文件的大小。对于内存受限的服务器(大多数已加载的服务器),删除一些扩展并将内存使用量从9减少到7兆,导致更多的apache worker运行。

不会共享此开销,因为每次执行都是PHP执行的单独副本。使用线程安全版本可以使用替代版本,但并非所有PHP扩展都是线程安全的。

删除扩展程序 看看你正在使用的功能。 mysqli_*xml_*?另外看看PHP是如何构建的,这是我的配置行:

Configure Command => './configure' '--with-apxs2=/usr/local/apache2/bin/apxs' '--with-mysql=mysqlnd' '--with-gd' '--enable-soap' '--with-libxml-dir=/usr/lib/' '--with-mysql-sock=/tmp' '--with-tidy' '--with-jpeg-dir=/usr/lib/' '--with-xsl' '--with-curl' '--with-zlib' '--enable-gd-native-ttf' '--with-openssl' '--with-mcrypt' '--with-pdo-mysql=mysqlnd' '--with-mysqli=mysqlnd' '--with-bz2' '--enable-bcmath'

如果我正在削减内存,我将首先使用./configure --disable-all构建PHP(以删除默认扩展名),然后显式添加我正在使用的新扩展名。我不再使用libxml作为我的代码,也不是soap所以我可以放弃这些位。我可以将我的tidy工作外包给一个齿轮工人和命令行,所以我也会把它拉出来。然后运行我的代码(在这里进行单元测试会非常棒)并看到什么破坏了。使用所需的扩展重新构建PHP,冲洗并重复。显然,不要在生产中执行此操作,否则您将拥有Bad Time

答案 1 :(得分:0)

Bytes vs Bits是10分之一。因此1.3 MBytes = 13MBits