php - fatal error : Out of memory, 但我确实有足够的内存 (PHP)

标签 php memory

由于我的问题越来越长,我决定重写整个问题以使其更好更短。

我在具有 8GB 内存的专用服务器上运行我的网站。我完全知道我需要提高 php.ini 设置的内存限制。我已将其从 128M 设置为 256M 和 -1。问题仍然是持久性。

Fatal error: Out of memory (allocated 786432) (tried to allocate 24576 bytes) in D:\www\football\views\main.php on line 81

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

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

提示

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

服务器规范

OS: Windows 2008 R2 64-Bit
CPU: Intel Core i5 - 4 cores
RAM: 8 GB
Apache 2.2
PHP 5.3.1
Storage: 2 x 1 TB hard drives
Bandwidth: 10 TB per month

解决方案

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

  1. favicon.ico 丢失了,这弄乱了我的路由引擎。虽然我的路由引擎很小,但通过包含 favicon.ico,它有助于通过不运行我的路由引擎来减少内存使用。我网站的大部分部分都有它,但我忘了把它放在这个新部分。
  2. Limit MaxRequestPerChild 有帮助。在我的另一台专用服务器中,我的 MaxRequestPerChild 受到限制。对于这个服务器,我设置为0。我一直以为每个脚本都是隔离的。假设我的脚本需要 800kb 才能运行。完成后,Apache 或 PHP 应该释放 800kb 内存。似乎它不以这种方式工作。有限的 MaxRequestPerChild 确实有助于防止内存泄漏,方法是在有限的 MaxRequestPerChild 之后创建新进程并且旧进程正在死亡。这是我的新设置。

    ThreadsPerChild      1500
    MaxRequestsPerChild  10000 
    
  3. ob_flush(); 确实会稍微减少一些内存。它没有多大帮助,但每一点优化都有帮助。

  4. 我使用了 xdebug,这是我以前从未使用过的,正如试图回答这个问题的人所建议的那样。我不得不说它是一个很棒的工具,我已经优化了一些东西,让它运行得更快。
  5. 我禁用了一些不必要的 Apache 模块。我正在尝试一一禁用它,并对其进行几天的测试,以确保它在禁用另一个之前完美运行。我现在确实禁用了所有不必要的 PHP 扩展。
  6. 我在这个服务器中的大部分脚本都使用传统方式(无模板、无数据库层、纯 PHP、HTML 和遗留 mysql_* 函数)。老实说,它运行速度非常快,而且使用的内存非常小。但是,由于网站越来越长,维护脚本并不容易。我试图将网站的某些部分转换为适当的框架(我自己的小框架)。我使用自己的框架的原因是它很小(整个框架只有 3kb,只包含我需要的内容)。
  7. 切换到 IIS7.5 彻底解决了这个问题

最佳答案

我在尝试使用交换时遇到了与服务器死机相同的问题。这是因为 mod_php 永远不会释放内存。因此,Apache 进程不断增长,要么达到 apache 或 PHP 的内存限制,要么,如果没有限制,则使服务器崩溃。

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

解决方案是让 apache 在提供一定数量的查询后终止进程,以便创建新的(有 some questions related to that)减少 MaxRequestsPerChild配置选项,假设为 100(默认为 1000)。

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

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

关于php - fatal error : Out of memory, 但我确实有足够的内存 (PHP),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12015569/

相关文章:

php - 处理标签

php - MySQL 按计数子字符串分组

php - 什么时候在 PHP 中使用 trait 是合适的?

php - 检查行是否插入/更新/删除偏执编程?

php - 检查数组中有多少值大于 x

unix - lsof FD 列等于DEL,是什么意思?

c# - 原生到托管编码(marshal)处理具有随机值

assembly - 为什么我们使用字节寻址而不是字寻址?

python - NumPy 中广播操作的内存增长

java - JDBC 占用内存大吗?