如何调试php“内存不足”问题?

2022-08-30 13:42:46

我最近遇到了一些PHP内存限制的问题:

内存不足(分配22544384)(尝试分配 232 字节)

这些都是调试的麻烦,因为我没有留下很多关于导致问题的原因的信息。

添加关机功能很有帮助

register_shutdown_function('shutdown');

然后,使用error_get_last();我可以获取有关最后一个错误的信息,在这种情况下,“内存不足”致命错误,例如行号和php文件名。

这很好,但是我的php程序是高度面向对象的。堆栈深处的错误并不能告诉我有关错误时刻的控制结构或执行堆栈的太多信息。我尝试过debug_backtrace(),但这只是在关闭期间向我显示堆栈,而不是错误时的堆栈。

我知道我可以使用ini_set或修改php.ini来提高内存限制,但这并不能让我更接近于真正弄清楚什么消耗了这么多内存,或者我的执行流在错误期间是什么样子的。

有人有一个很好的方法来调试高级面向对象PHP程序中的内存错误吗?


答案 1
echo '<pre>';
$vars = get_defined_vars();
foreach($vars as $name=>$var)
{
    echo '<strong>' . $name . '</strong>: ' . strlen(serialize($var)) . '<br />';
}
exit();

/* ... Code that triggers memory error ... */

我用它来打印出当前分配的变量列表,就在代码的问题部分之前,以及变量大小的(非常)粗略估计。我回去,任何在兴趣点和兴趣点之外不需要的东西。unset

当安装扩展不是一个选项时,它很有用。

您可以修改上述代码,使其以一种对您变量中的内存进行不同估计的方式使用,不确定它是更好还是更糟。memory_get_usage


答案 2

Memprof是一个php扩展,可以帮助找到那些吞噬内存的片段,特别是在面向对象的代码中。

这个改编的教程非常有用。

注意:我试图为Windows编译此扩展程序,但没有成功。如果你这样做,请确保你的php不是线程安全的。为了避免一些麻烦,我建议您在*nix环境下使用它。

另一个有趣的链接是描述php如何处理内存的幻灯片共享。它为您提供了有关脚本内存使用情况的一些线索。


推荐