【问题标题】:Tracking memory leaks in a large codebase跟踪大型代码库中的内存泄漏
【发布时间】:2012-08-10 05:31:57
【问题描述】:

对于使用CodeIgniter 构建的应用程序,我有一个相对较大的 PHP 代码库(数千行)。为了能够跟踪性能问题并能够生成统计数据等,开发服务器运行Xhprof。如果脚本实际上进入了日志记录部分,这可以正常工作。

但是,我现在遇到了脚本超时的情况。在开发服务器上,它只是给出一个超时(“未找到服务器”)错误,有时甚至会导致 Apache 进程崩溃。不生成 Xhprof 文件,CodeIgniter 日志系统不生成任何内容。错误报告已启用。

在实时环境中(嗯,实时服务器的镜像),应用程序实际上会产生错误:

致命错误:第 493 行 /home/www/application/system/database/drivers/mysql/mysql_driver.php 中允许的内存大小为 33554432 字节已用尽(尝试分配 261900 字节)

这一点,以及关于如何重现错误的线索,让我有点预感从哪里开始寻找解决方案。但这是一项耗时的工作。

我正在寻找一种能够追踪实际“内存泄漏”发生位置的方法。 而不是逐行手动调试。非常感谢任何建议。

更新:服务器内存不足不是问题。在具有更多内存的开发服务器上,也会出现同样的问题。问题是一个无限循环,分配了更多的内存,然后我的服务器可以处理。问题仍然存在:如何快速追踪这些错误?

【问题讨论】:

  • 32MB 并不是很多余量,这取决于您的应用程序需要做什么。您确定您不需要更多内存来处理从数据库返回的数据吗?
  • @Brad 我确定我在某个地方有一个坏循环或类似的循环,它不断分配内存。但是,追踪它是一项艰巨的工作:-)
  • PHP 不会泄漏内存,它有一个垃圾收集器,任何时候变量或对象超出范围,它都会自动进行垃圾收集。但我同意 Brad 的观点,32MB 并不是很多内存。只需阅读有关 how large PHP arrays are 的内容,您就会发现即使是一个小数组也会消耗大量内存。
  • 您的mysql_driver.php 脚本的第 493 行是否将结果循环放入数组中?您可能将“太多”结果放入数组中。
  • @drew010 我知道,我无法为我的问题找到一个更“合适”的词。这绝对是我的代码而不是服务器设置的错误。在拥有大量内存的开发服务器上,它仍然无法运行。

标签: php codeigniter memory-leaks xhprof


【解决方案1】:

使用xdebug。与 xhprof 不同,使用 xdebug 进行分析会在脚本运行时产生输出,这意味着即使脚本挂起或超时,您也可以剖析到该点生成的跟踪。

另请参阅Profiling with xdebug 以开始使用。

【讨论】:

  • 正是我想要的。非常感谢!
  • @Zar 没问题,请注意 xdebug 没有 Web 界面,一开始可能看起来很奇怪,但是 Linux 上的 KCacheGrind 或 win 上的 WinCacheGrind 等工具为 xdebug 的输出提供了一个很好的界面.
【解决方案2】:

打算保留统计信息的程序的一个常见问题是,保留指针指向它们接触的所有内容,这会阻止内存管理回收它们。如果不是这种情况,这可能不是泄漏,它可能只是一个失控的分配。您可能只有少数几个地方可以这样做。一个好的开始是替换对系统函数的直接调用 用你自己的函数分配内存块,然后检测这些函数,寻找 用于意外的大数组分配。

按照现代标准,引用的限制 (32mb) 并不是很大。很容易出现这样的情况,除了进程有不合理的下限之外没有任何问题。

【讨论】:

    猜你喜欢
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多