提问人:Nate 提问时间:7/24/2014 最后编辑:Nate 更新时间:11/3/2016 访问量:9911
如何避免“记忆......在自定义错误处理程序中使用 debug_backtrace() 时出现“exhausted”错误?
How to avoid “memory … exhausted” error when using debug_backtrace() in custom error handler?
问:
我为我的网站编写了一个错误处理程序,如下所示:
function errorHandler($number, $string, $file, $line, $context, $type = '') {
// save stuff in DB
}
我是这样注册的:
set_error_handler('errorHandler', E_ALL);
我将所有传递的变量保存在数据库中,以及一个回溯跟踪来帮助我调试问题:
print_r(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT), true)
问题是我有时会收到此错误:
允许的内存大小已耗尽 134217728 字节(尝试分配 30084081 个字节)
错误处理程序在出现上述错误时运行的原因是,我在创建 Amazon S3 对象(来自他们的 PHP AWS 库)后尝试使用未定义的变量。我假设,因为 Amazon AWS 库非常庞大,以至于回溯正在提取大量数据,这会导致内存不足错误 (?)。
我想在可能的情况下包含回溯以帮助调试,但是如何防止调用函数导致致命错误(在我的错误处理程序中,这有点讽刺..)?debug_backtrace()
答:
您可以为您的debug_backtrace设置限制。
print_r(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 50), true);
评论
50
1
尝试增加内存限制:
ini_set("memory_limit","256M");
print_r(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT), true);
评论
ini_set()
我怀疑你只需要删除DEBUG_BACKTRACE_PROVIDE_OBJECT
可能是您的代码在对象中具有循环引用,这意味着在转储它们时,它会循环直到消耗所有内存。
另一种替代方法是抛出并捕获异常,然后使用它来获取回溯
try{
throw new Exception();
}catch(Exception $e){
echo $e->getTraceAsString();
}
http://php.net/manual/en/exception.gettraceasstring.php
或者,如果您需要冗长,请尝试 print_r($e->getTrace());
http://php.net/manual/en/exception.gettrace.php
评论
debug_backtrace()
首先检查它是否真的是令人筋疲力尽的记忆。 一旦我遇到这个错误,我就追溯到一个无限循环。
由于您的服务器不允许ini_set,我建议您在本地系统复制它并将内存增加到 1GB 并检查内存是否仍然耗尽,这是一个无限循环。
可能不是最好的答案,但您是否考虑过使用 var_dump 而不是 print_r?var_dump只下降了几个嵌套级别,因此 EdmondsCommerce 提到的循环引用问题不会导致您的内存耗尽。
评论
var_dump
除非安装了 XDebug 扩展,否则会一直下降。;)
如果可能的话,我会建议用DEBUG_BACKTRACE_PROVIDE_OBJECT
DEBUG_BACKTRACE_IGNORE_ARGS
评论