重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
原文地址:https://www.airpair.com/php/fatal-error-allowed-memory-size
创新互联公司是一家集网站建设,织金企业网站建设,织金品牌网站建设,网站定制,织金网站建设报价,网络营销,网络优化,织金网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
内存不足错误是PHP开发人员遇到的最常见和难以解决的问题之一 - 特别是对于处理大量数据的应用程序 - 这要归功于PHP相对保守的默认内存设置。事实上,仅Stack Overflow上有超过1,300个与PHP内存错误相关的问题。
98%的时间此错误来自加载到内存中的内容比您在一个进程中设置PHP要处理的内容多。还有其他原因,但这些不太常见 - 如果您使用的是PHP 5.3及更高版本,则很少会出现内存泄漏。
如果您不确定您的PHP内存限制设置为什么,它将有助于包含在错误消息中。但是,大小以字节为单位报告,因此我们为您完成了一些转换:
您的第一个行动是增加内存限制。注意,这是一个临时调试生产。目标是将内存增加到我们让应用程序再次工作以减少内存使用量的程度。一旦减少了内存使用量,就可以将内存限制降低到更合适的值。您的计划应该是使用尽可能少的内存,因为应用程序可以在生产服务器中根据用户(人或程序)的工作负载正常运行。我通常建议将内存限制设置为高,例如1GB,假设你在RAM中至少有150%的空闲内存。
此外,永远不要在生产服务器上进行这些测试,除非您确定您有足够的RAM 并且您完全理解Web服务器进程如何消耗内存。如果有许多并发进程在运行,每个进程都使用大量内存,您可以轻松地使服务器陷入困境。我绝不会建议-1在生产环境中将内存限制设置为(无限制)。那是一场灾难。不要犯那个新手的错误。
那你怎么做的?简单 - 在进程耗尽内存之前,在代码的早期以编程方式增加内存限制。如果以这种方式执行,只有在调用该段代码时才能为PHP提供额外的内存,而不是增加所有 PHP进程的内存限制。
打电话给急诊室,因为你可能会在那里结束。不,说真的,这里有几件你可以做的事情。
首先,你需要问问自己什么时候开始发生。以前是否有效,现在不是吗?如果是这样,请考虑可能发生的变化。隔离问题。
在问题出现之前,您可能没有触摸过代码。那么,还有什么可以改变的呢?有外部依赖吗?也许是数据库或用户导入的文件?把它放在你的嫌疑人名单上并开始调查。
从小开始; 从你“思考”问题开始,并试图证明自己是错的。如果你不能,继续前往下一个嫌犯。看看你的代码在它过早退出之前进入了多远,然后从那里开始处理调用堆栈(var_dump debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)如果你没有安装Xdebug)。如果您可以使用Xdebug或Zend Debugger进行交互式调试,请执行此操作并在问题区域之前放置断点。
我曾经遇到过导入后Excel文件内存不足的问题。几个月来它工作正常,但突然停了下来。我觉得我花了至少5小时的不懈调试之前,我发现了问题:在某种程度上被插入随机数据,一个工作表的单元用户的。显然PHP只是乱了,我仍然没有发现根本原因,尽管知道触发器。
通过问自己改变了什么,我可以节省很多时间。答案非常明显 - 用户和数据库输入的数据。你可以有类似的经历。
在任何情况下,都可以依靠一个工具来帮助诊断您正在使用的内存量以及代码中使用大量内存的位置:Xdebug。您可以使用软件包管理器如安装yum,apt-get,port,和homebrew; 安装预先构建的二进制文件; 使用pecl; 或者只是自己编译。
安装Xdebug之后,您只需刷新页面,或者如果您的代码要在shell中运行,请在CLI中重新运行它。PHP现在将抛出更多信息性错误,包括一个调用堆栈,它将通过文件路径,行号甚至最后调用的函数准确地告诉您脚本停止的位置。
如果您需要更详细的信息,您需要生成所谓的“跟踪文件”。为此,请将xdebug.auto_traceand和xdebug.show_mem_deltaconfig指令设置为1。跟踪文件通常保存在/tmp或中/var/tmp,但您可以通过查看xdebug.trace_output_dir指令来检查输出路径phpinfo()。
只需运行代码,即使早期内存不足,也会创建跟踪文件(包括内存使用情况)。
要找到问题,请从跟踪文件的底部开始,然后逐步完成。查找具有大数字的增量(带有+或 - 的数字),并记住它们以字节显示。1024字节= 1千字节。
完成调试后,请务必xdebug.auto_trace回到0。跟踪文件可能变得非常大,非常快,并占用磁盘空间。
这是一个关于PHP如何在内部处理内存的精彩幻灯片。
使用以下脚本并尝试查明问题所在。更好的是,安装Xdebug并生成跟踪文件。
startTime = microtime(true);
}
function timerEnd(){
echo number_format( (microtime(true) - $this->startTime)*1000, 2 ), ' ms';
}
}
class ProfilerHolder {
protected $profiler;
public function __construct( Profiler $profiler ){
$this->profiler = $profiler;
}
}
ini_set('memory_limit', '1M');
$profiler = new Profiler();
$profiler->timerStart();
get_usage_in_kb();
$holder = new ProfilerHolder( $profiler );
$b = null;
/**
* @return string
*/
function make_dummy_data()
{
return str_repeat( "Hello|", 114242 );
}
考虑到所有这些提示,您应该能够修复任何内存耗尽错误。