由于我的问题越来越长,我决定重新编写整个问题,以使其更好更短。
我在具有8GB内存的专用服务器上运行我的网站。我完全清楚我需要提高php.ini设置的内存限制。我把它从128M设置为256M并设置为-1。问题仍然是持久性。
致命错误:内存不足(已分配786432)(尝试分配24576 在第81行的D:\ www \ football \ views \ main.php中
内存不足没有意义,因为它说只分配了786432个字节,而且需要24576个字节。
786432字节只有768千字节,而且相当小。
echo memory_get_peak_usage();
操作系统:Windows 2008 R2 64位 CPU:Intel Core i5 - 4核心 RAM:8 GB
Apache 2.2
PHP 5.3.1
存储:2 x 1 TB硬盘
带宽:每月10 TB
我终于调整并解决了问题,我想在此分享我所做的改进:
favicon.ico
遗失了,这与我的路线引擎相混淆。虽然我的路由引擎非常小,但是通过包含favicon.ico
,它可以通过不运行我的路由引擎来减少内存使用量。我网站的大部分内容都有它,我忘了把它放在这个新的部分。限制MaxRequestPerChild
有帮助。在我的其他专用服务器中,我的MaxRequestPerChild
有限制。对于这台服务器,我将其设置为0.我一直认为每个脚本都是隔离的。让我们说如果我的脚本运行800kb。完成后,Apache或PHP应该释放800kb内存。看起来它不会这样工作。限制MaxRequestPerChild
确实有助于通过在限制MaxRequestPerChild
之后创建新流程来防止内存泄漏,并且旧流程正在消亡。这是我的新设置。
ThreadsPerChild 1500
MaxRequestsPerChild 10000
ob_flush();
确实会减少更多内存。它没有多大帮助,但每一点优化都有帮助。
xdebug
,这是我以前从未使用的,正如那些试图回答这个问题的人所建议的那样。我不得不说这是一个很好的工具,我已经优化了一些东西,使它运行得更快。答案 0 :(得分:26)
在尝试使用交换时,我遇到与服务器死亡相同的问题。这是因为 mod_php永远不会释放内存。因此,Apache进程不断增长,无论是达到apache还是PHP的内存限制,如果没有限制,都会使服务器崩溃。
重新启动apache使它产生新的细微进程但随着时间的推移运行PHP脚本,它们会一直增长直到出现问题。
解决方案是在提供一定数量的查询之后使apache杀死进程,这样它就会创建新的(some questions related to that}将MaxRequestsPerChild配置选项减少到,假设为100(默认值)到1000)。
当然,这可能会降低服务器性能,因为它需要资源来杀死和生成新进程,但至少它会保持站点正常工作。您可能想提高运行进程的数量以保持高性能,确保PHP(或apache)内存限制x max进程数不会超过服务器的物理RAM。
这是我的经历,希望有所帮助。
答案 1 :(得分:15)
首先,memory_get_peak_usage()
在这里没有帮助。它只返回分配的内存量,这与导致错误的数字相同。
memory_get_usage
将返回调用时分配的活动内存量。
ini_set('memory_limit', '256M');
将设置PHP占用系统内存的最大容限。如果你在768K获得OOM,那么增加它将无法解决问题。
没有迹象表明您使用的是哪个版本的PHP,但我建议立即升级。有几个错误,Zend的内存管理器无法释放内存,这将导致你完全出现同样的问题。
您的本地服务器和生产服务器是否都运行相同版本的操作系统,相同的长位和相同版本的PHP?答案是否定的。
如果它与windows malloc()
问题无关,因为它是一个子域,可能在VirtualHost中,并且只分配768k,这几乎听起来像操作系统问题。
访问脚本时从命令提示符运行tasklist
。你看到一个额外的Apache线程,还是整个进程中的内存使用率飙升?
最后一个想法是,在表行/列的每个循环之后运行flush()
和/或ob_flush();
。如果出现问题,这应该清除缓冲区并为您节省一些内存。
答案 2 :(得分:8)
我首先将PHP升级到5.4+,因为某些应用程序的速度提高了50%。 他们修复了大量的内存泄漏。请参阅becnhamrks:http://news.php.net/php.internals/57760
答案 3 :(得分:6)
安装xdebug并启用探查器触发器。 生成一个探查器文件,然后发布cachegrind文件,如果你仍然无法告诉问题的根源。
编辑:当然发生内存泄漏的页面的探查器文件!
答案 4 :(得分:5)
请注意,错误为Out of memory
且不是Allowed memory size [..] exhausted
。
因此内存泄漏在系统的其他地方。在这个繁重的查询之后,mysql服务器可能会使用大量的系统内存,而apache / php没有物理和交换。
这应该总是在同一行(和/或同一个脚本)中解释错误。
答案 5 :(得分:4)
我猜你要么没有编辑正确的php.ini
,要么你还没有重新启动PHP和/或网络服务器。
在docroot中使用内容phpinfo.php
创建<?php phpinfo();
页面,以确保您更改了正确的php.ini
。除了Web服务器正在使用的php.ini
文件的位置之外,它还将声明允许的最大脚本内存。
接下来,我会向您的页面添加一些堆栈跟踪,以便您可以看到导致此问题的事件链。以下函数将捕获致命错误并提供有关所发生情况的更多信息。
register_shutdown_function(function()
{
if($error = error_get_last())
{
// Should actually log this instead of printing out...
var_dump($error);
var_dump(debug_backtrace());
}
});
就个人而言,Nginx + PHP-FPM是我多年来使用的,因为我离开了慢慢的'Apache。
答案 6 :(得分:3)
嘿我在我的服务器上也遇到了同样的问题。我刚刚更改了以下内容:
将php.ini
更改为...
memory_limit = 128M
并添加到httpd.conf
RLimitMEM 1073741824 2147483648
并重新启动apache&amp;我删除了错误:
答案 7 :(得分:3)
可能是MySQL的问题和开放连接的数量,因此当你每隔几天重新启动时它会自行排除。它们是否在脚本关闭时自动关闭?
答案 8 :(得分:2)
回顾一下(我将此答案与原始问题相距很远):
如果这些都是有效的,那么唯一可能的解释是6Gb 非常支离破碎 - 我认为这有点不太可能。您没有说过如何从Apache调用PHP - mod_php? FPM? FCGI?
我将从检查上述每个谓词开始 - 特别是免费记忆。你怎么知道发生错误时有6Gb的免费 ?更可能的原因是发生了内存泄漏,而您没有发现。
您没有提供有关如何配置apache的任何详细信息;我还要看看减少MaxRequestsPerChild和MaxMemFree。 (我对每个线程都适用的工作者apache不太熟悉 - 实际上你需要每个进程限制一次)。如果您从apache配置中提供了核心设置,那么我们可能会提出进一步的建议。
除非您广泛使用Ajax,否则请确保您的保持活动时间为2或更短。
答案 9 :(得分:1)
让我们说当你访问这个网址 http:// localhost / mysite / page_with_multiple_requests
如果收到多个请求,请检查Apache的访问日志。跟踪该请求并检查可能导致系统“瓶颈”的代码(使用sendmail时我的exec())。我所谈论的瓶颈并不一定是“无限循环”。它可能是需要一些时间才能完成的功能。或者可能是某些PHP的'program execution functions'
您可能还需要检查ajax请求(页面加载时执行的请求)。如果该ajax请求重定向到相同的URL
e.g。 httpx://本地主机/ mysite的/ page_with_multiple_requests
它将重新“重做”请求
如果您发布随机行或代码本身,脚本结束可能会有帮助,也许在某处存在“循环”代码。 imho php不会只是随意调用随机行。
http://blog.piratelufi.com/2012/08/browser-sending-multiple-requests-at-once/
答案 10 :(得分:1)
以下两个事实肯定指向内存泄漏:
我首先会选择PDO,禁用所有其他扩展,让它在一夜之间使用Siege / Apache Bench(ab)运行。您也可以尝试使用cli
界面运行它(只需确保保持相同的内存限制)。
您可以使用脚本末尾的memory_get_peak_usage()
函数来查看PHP认为已使用的内存量。
你的评论是800 kB,这没关系;绝对不是会导致内存不足的巨大内存量; - )
最后,虽然我不建议此时升级到5.4,但升级到最新的5.3.x可能是值得的,因为自5.3.1以来已经解决了多个漏洞和泄漏
答案 11 :(得分:1)
大多数时候你会遇到这样的错误,问题在于代码。我并不是说你编写的代码很糟糕,我试图说你需要仔细观察使用这么多内存的内容。
永远记住“ PHP中的垃圾收集非常糟糕”,它不像Java,任何其他类似语言。有一种方法可以通过 gc_collect_cycle 强制执行垃圾收集,但是,在我个人看来,这不会解决您的问题。 PHP释放所有用于执行页面的内存,一旦请求 - 响应周期完成,所以你可能遇到内存问题,如果你的脚本长时间运行,就像后台脚本(Gearman等),因为,内存不会释放直到脚本正在运行。
如果你的scr,pt不是这样,并且正如你所说的那样,没有需要如此大量内存的代码,那么问题绝对是代码本身,并升级到任何版本的PHP赢了解决问题。我曾经面对过我的一个Gearman脚本,并且我的一个循环出现问题,我将一个变量附加到我的一个数组中,变量本身非常重(大约110KB的数据)。所以我建议,仔细检查你的代码。
狂喜
答案 12 :(得分:1)
我遇到了与PHP类似的问题:
1)检查错误日志。在继续之前消除每个错误。 2)考虑修改你的apache配置以消除未使用的模块 - 这将减少PHP所需的占用空间 - 这是一个很好的链接 - 它是特定于Wordpress但仍然非常有用http://thethemefoundry.com/blog/optimize-apache-wordpress/
为了让您了解我发现的错误类型,我有一些代码试图将内容发布到Facebook,Facebook然后修改了他们的API,所以这破坏了,我还使用了“内容expirator”,这基本上意味着它一直在重试将这些内容发布到Facebook,并将大量对象留在内存中。
答案 13 :(得分:1)
从探查器输出文件中我注意到了一些我不喜欢/不相信的东西,并会研究这些:
除了不知道输出数字的含义以检测异常或PHP脚本如何工作......,这不是问题吗?有一个include到相同的main.ph文件,看起来像一个递归的东西?
2121 fl=D:\www\football\views\main.php
2122 fn=include::D:\www\football\views\main.php
注意文件D:\www\football\views\main.php
多次使用一些字符串函数,我猜它是在查询返回的数据上调用这些函数:
strlen
substr
strtotime
如果像在C语言中一样,这些函数需要字符串null
终止或字符串终结符的另一端以避免内存问题,我会查看查询返回的字符串。
您可以发布您网站的网址吗?
答案 14 :(得分:1)
这是PHP v 5.2 for Windows中的已知错误,它至少存在于5.2.3版本中:https://bugs.php.net/bug.php?id=41615
没有任何建议的修复程序对我们有帮助,我们将不得不更新PHP。
答案 15 :(得分:1)
尝试在fcgid上运行php,这可能会有所帮助:
这些是您在运行PHP时会看到的经典错误 Apache模块。几个月来我们一直在努力解决这些错误。切换到 通过mod_fcgid使用PHP(正如James推荐的那样)将解决所有这些问题 问题。确保您拥有最新的Visual C ++ Redistributable 包安装:
http://support.microsoft.com/kb/2019667
另外,我建议切换到64位版本的MySQL。不真实 之所以再次运行32位版本。
来源:Apache 2.4.6.0 crash due to a problem in php5ts.dll 5.5.1.0
答案 16 :(得分:1)
致命错误:内存不足(分配已解决
我有类似的问题,几个月没有解决方案。最后我检查了一个apache文件夹,即(\ apache \ conf \ extra)我遇到了这个控制apache内存分配的文件。文件名是 httpd-mpm 在那个文件中你要将MaxMemFree设置为2048更高的东西,我把我的第一个MaxMemFree(IfModule!mpm_netware_module)拿到10000然后做第二个MaxMemFree为5000 IfModule mpm_netware_module。
这些解决了我的问题。希望它有所帮助
答案 17 :(得分:0)
我会说服务器的物理/交换内存不足,所以PHP无法分配足够的内存。
您可以在此处粘贴free
的输出吗?
答案 18 :(得分:0)
对于我的情况,由于巨大的选择查询(数十万返回的结果)而触发了此错误。
在我的数据库中添加数百万条记录后立即出现,以测试WordPress的可扩展性,所以这是我唯一可能的原因。
答案 19 :(得分:0)