首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >致命错误:内存不足,但我有足够的内存(PHP)

致命错误:内存不足,但我有足够的内存(PHP)
EN

Stack Overflow用户
提问于 2012-08-18 11:23:04
回答 20查看 118.8K关注 0票数 67

由于我的问题越来越长,我决定重写整个问题,使它变得更好和更短。

我在8 8GB内存的专用服务器上运行我的网站。我完全意识到我需要提高php.ini设置的内存限制。我已经将它从128M设置为256M,并设置为-1。问题仍然是持久力。

致命错误:第81行的D:\www\football\views\main.php中内存不足(已分配786432) (尝试分配24576字节)

内存不足没有任何意义,因为它只分配了786432字节,还需要24576字节。

786432字节只有768千字节,而且相当小。

提示

  • 错误发生在非常随机的一行上。它并不总是在第81行出错。
  • 在高峰期,Apache只占用大约500mb的内存。我还有6 6GB的空闲空间。
  • 没有无限循环。
  • 脚本占用了1,042,424字节。从Apache的echo memory_get_peak_usage();
  • The结果集获取这个数字很小(最多12行,纯文本,没有blob data)
  • (Important)如果我每两天重新启动MySQL一次,错误就会消失。它通常发生在Apache运行超过2天的时候。
  • 我已经包含了脚本的分析,你可以得到它,here.
  • This专用服务器只用于运行一个网站。这个网站是一个高流量的网站,平均每分钟有1000名访问者。在高峰期,将有1,700到2,000名访问者同时访问。

服务器规格

操作系统: Windows 2008 R2 64位

处理器:英特尔酷睿i5 -4内核

RAM: 8 GB

Apache 2.2

PHP 5.3.1

存储:2个1 TB硬盘

带宽:10TB/月

解决方案

我终于调整并解决了这个问题,我想在这里分享我所做的改进:

  1. favicon.ico丢失了,这搞乱了我的路由引擎。虽然我的路由引擎非常小,但是通过包含favicon.ico,它可以通过不运行路由引擎来帮助减少内存使用。我网站的大部分内容都有它,但我忘了把它放在这个新的section.
  2. Limit MaxRequestPerChild帮助中。在我的另一台专用服务器上,我的MaxRequestPerChild是有限的。对于此服务器,我将其设置为0。我一直认为每个脚本都是孤立的。假设我的脚本需要800kb才能运行。完成后,Apache或PHP应释放800kb内存。它似乎不是这样工作的。有限的MaxRequestPerChild确实有助于防止内存泄漏,因为在有限的MaxRequestPerChild之后创建新的进程,而旧的进程正在消亡。这是我的新设置。

ThreadsPerChild 1500 MaxRequestsPerChild 10000

  • ob_flush();会稍微减少一些内存。它没有多大帮助,但每一点优化都有帮助。

  • ,我用过xdebug,我从来没有用过,这是那些试图回答这个问题的人建议的。我不得不说这是一个很棒的工具,我优化了一些东西,让它运行得更快。

  • ,我禁用了一些不必要的Apache模块。我正试着一个接一个地禁用它,并让它在我禁用另一个之前测试几天,以确保它能正常工作。

  • 我在这个服务器上的大部分脚本都使用了传统的方式(没有模板,没有数据库层,纯PHP,HTML和遗留的mysql_*函数)。老实说,它运行得非常快,占用的内存也非常小。然而,维护脚本并不是很容易,因为网站越来越长。我试着把网站的一些部分转换成合适的框架(我自己的小框架)。我之所以使用我自己的框架,是因为它很小(对于整个框架来说,它只有3KB,并且只包含我need).

  • Switching到IIS7.5的内容,从而解决了这个问题completely.
EN

回答 20

Stack Overflow用户

发布于 2012-08-29 20:42:32

我运行时遇到了同样的问题,服务器在尝试使用交换时死了。这是因为mod_php不会在中释放内存。因此,Apache进程不断增长,要么达到apache或PHP的内存限制,要么使服务器崩溃。

重新启动apache会产生新的瘦进程,但随着时间的推移,它们会不断运行PHP脚本,直到出现问题。

解决方案是让apache在处理一定数量的查询后杀死进程,这样它就会创建新的进程(有some questions related to that),将MaxRequestsPerChild配置选项减少到100 (缺省为1000)。

当然,这可能会降低服务器性能,因为它需要资源来杀死和产生新的进程,但至少它保持了站点的工作。你可能想增加运行进程的数量以保持高性能,请确保PHP (或apache)内存限制x最大进程数不会超出服务器的物理内存。

这是我的经验,希望能有所帮助。

票数 30
EN

Stack Overflow用户

发布于 2012-08-29 00:17:29

对于初学者来说,memory_get_peak_usage()在这里不会有什么帮助。它将只返回已分配的内存量,这与导致错误的内存量相同。

调用memory_get_usage时,它将返回正在分配的活动内存量。

ini_set('memory_limit', '256M');将设置系统内存中允许的最大内存占用量。如果你在768K获得OOM,增加它将不会解决问题。

没有任何迹象表明您使用的是什么版本的PHP,但我建议立即升级。有几个bug,Zend的内存管理器无法释放内存,这将导致完全相同的问题。

您的本地服务器和生产服务器是否运行相同版本的操作系统、相同的长位和相同版本的PHP?答案将是否定的。

如果它与windows malloc()问题无关,因为它是一个子域,可能在VirtualHost中,并且只分配768k,那么它听起来几乎就像是操作系统问题。

访问脚本时,从命令提示符运行tasklist。您是否看到一个额外的Apache线程,或者跨进程的内存使用率峰值?

最后一个想法是,在表行/列的每个循环之后运行flush()和/或ob_flush();。这应该会清除缓冲区,并在发生问题时节省一些内存。

票数 15
EN

Stack Overflow用户

发布于 2012-08-27 16:56:00

我会从将PHP升级到5.4+开始,因为对于某些应用程序来说,它的速度要快50%。他们修复了大量的内存泄漏。请参阅becnhamrks:http://news.php.net/php.internals/57760

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12015569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档