【问题标题】:memory_get_usage seems inaccurate, how can I further diagnose a memory leak in PHP?memory_get_usage 似乎不准确,如何进一步诊断 PHP 中的内存泄漏?
【发布时间】:2015-01-22 20:26:34
【问题描述】:

我看到我长期运行的 php 进程占用了大量内存,并且增长非常快。大约一天后,我看到了以下内容:

# pmap <pid>  

000000000091c000    588K rw---  /usr/bin/php  
00000000009af000    108K rw---    [ anon ]  
00000000013ab000 256948K rw---    [ anon ]  
00007f9ed0000000    132K rw---    [ anon ]  
...  
00007f9edcaa6000      8K rw---  /usr/lib64/php/modules/curl.so  
00007f9edcaa8000 103580K r----  /usr/lib/locale/locale-archive  
...  
 total           629312K  

# cat /proc/<pid>/status  


Name:   php  
State:  S (sleeping)  
...  
VmHWM:    268920 kB  
VmRSS:    268920 kB  
VmData:   334368 kB  
VmStk:       136 kB  
VmExe:      3188 kB  
VmLib:     22752 kB  
VmPTE:       912 kB  
VmSwap:        0 kB  
Threads:    1  
...  
Mems_allowed:   00000000,00000001  
Mems_allowed_list:  0  
voluntary_ctxt_switches:    11902137



ps aux  


0.5  4.3 694124 333864 ?       S    Jan21   8:11 php  

top  

PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  CODE DATA COMMAND  
20   0  677m 326m 9100 S  0.0  4.4   8:11.56 3188 390m php  

但是,memory_get_usage(true) 始终返回:
1835008

似乎存在内存泄漏,但如何诊断原因并减少它?我尝试使用this 等工具,但与memory_get_usage 类似,它不会注意到任何额外的内存使用

我也试过: # strace -p -e 跟踪=内存 但我看到的只是 brk() 调用,如下所示:

brk(0)                                  = 0x14f6f000
brk(0x14f90000)                         = 0x14f90000

我使用的是 5.4.27 版本:

# php --version
PHP 5.4.27 (cli) (built: Apr 23 2014 23:34:13)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies

【问题讨论】:

  • Xdebug 对长时间运行的脚本 afaik 没有很好的支持,但是:stackoverflow.com/questions/17648097/…
  • @MichaelBerkowski,这似乎对确定执行哪些代码非常有帮助,但不一定有助于查看内存使用情况。应该注意的是,我链接到的内存分析器在显示已执行的内容方面也做得很好。

标签: php


【解决方案1】:

您可以使用 --enable-debug 配置选项自行编译 PHP。如果您执行以这种方式编译的 php cli 脚本,您将获得有关检测到的内存泄漏的详细说明 - 如果有的话。

然而,memory_get_usage() 返回一个常量值的事实看起来很奇怪。你能把问题简化为一个脚本吗? (或者展示你的脚本?)你能把它归结为某些 PHP 扩展吗?您使用的是哪个版本的 PHP?

【讨论】:

  • 向 OP 添加了版本。但是,我无法显示我的脚本。 pmap 向我暗示它不是扩展,但是
  • 泄漏是否可重现?
  • 我会尝试用--enable-debug 编译PHP。 (如果不提供可重现的示例,您无法提交错误报告)
  • 我会调查它,但考虑到 php 没有看到额外的内存使用,这似乎有点远,你说“......你会得到一个关于检测到内存泄漏 - 如果有的话。”
  • 我不是 C 专家,尤其不是 C 开发工具专家,但我希望他们使用 valgrind - 这意味着 PHP 本身不会检测到泄漏(这没有任何意义)..我在扩展开发过程中使用了这个功能,发现它很有帮助。此外,当使用 PHP 的调试版本时,即使在“常规”脚本中,我也检测到内存泄漏。 regular 表示仅使用 PHP 核心功能的脚本。我发现泄漏不是很多,但也不是很少。因此,我鼓励你也这样做。 (除非您无法提供可重现的示例)...
猜你喜欢
  • 2018-10-24
  • 2012-10-09
  • 1970-01-01
  • 2021-10-01
  • 2021-09-14
  • 1970-01-01
  • 2013-07-11
  • 1970-01-01
  • 2014-06-16
相关资源
最近更新 更多