问题描述

我仔细看了一下 WordPress 内存消耗。在我的网站上,似乎每个页面都有 20MB 的 RAM 被分配,只是为了准备好所有的插件运行环境,我绘制了它:

 http://zenka.net/roman/wordpress_memory_consumption.gif

没有一个优点,没有一个坏家伙吃大部分的记忆。消费遍布许多很多 php 模块。

我们如何使 WordPress 在内存中初始化其环境一次,然后每次重复使用多次?我不想慢慢的 PHP 吃每个用户点击 20 MB – 即使在服务器上有大量的内存,需要几秒钟才能完成所有的工作。您将基本上需要可重复使用的 read-only 内存块。

还… 为什么 20MB?任何人都可以提供洞察力吗?

编辑:这是在我的开发机器上运行的 WordPress 上的 WinCacheGrind 输出 (比共享主机快得多) 。正如你所看到的,它需要一秒钟的时间才能生成主页的 HTML 。通过共享托管缓慢下来,你有一个麻烦的秘方。我选择了大部分时间需要的方法。你会如何优化这个?

 http://zenka.net/roman/wordpress_cpu_usage.gif

编辑:这里是 this fantastic functions.php profiling tool 的查询统计信息。


Load: 12 queries - 532ms - 19.1MB - 43 cache hits / 53
Query: 15 queries - 563ms - 19.0MB - 72 cache hits / 86
Display: 21 queries - 705ms - 19.2MB - 234 cache hits / 257

编辑:你想看到有什么可以吓倒你的吗?在 index.php 的末尾插入这些行:


echo "<pre>n";
print_r(get_defined_vars());
echo "</pre>n";

我试图计算当前帖子的身体存储在内存中的次数。我算了 20 个例子。然后我意识到 PHP 有引用计数,所以拷贝的数量减少到只有三个:两个似乎在 WP_Query 中,一个在对象缓存中。我正在进一步调查。

这就是为什么我认为 WordPress 需要重构针对内存问题。您不能再将其内存消耗归咎于其所做的复杂程度。它只是做了一堆事情错了。

编辑:经过一天的尝试,这是我的发现:

1)88%的内存来自 require 或 include 或 include_once 类型的呼叫:

 http://zenka.net/roman/wordpress_memory_requires.gif

2)php 文件主要发生在服务请求的第一部分 (不奇怪),这也是所有内存被吃掉的地方:

 http://zenka.net/roman/wordpress_includes.gif

3) 绘制请求时正在执行的所有功能非常有趣。共有 12000 多个电话。我激动他们使它更加明显 (水平轴基本上是堆叠的深度):

 http://zenka.net/roman/wordpress_functions.gif

4) 我可以想到的唯一的方法是最小化包含的.php 文件的数量。如果我们从每个文件中分离出来的功能,你可以看到很多文件最多被击中一次或两次。我们需要一种如何在不需要时跳过的方式。例如我的远程数据库备份插件被加载和注册,只是从来没有使用过。以上是以文件名分割的上述情节:

 http://zenka.net/roman/wordpress_functions_files.gif

我提供一个值得我所有声誉的赏金:),用于重构,这将导致我的博客的内存占用减少 30%以上。

编辑:我安装了 WP 3.1,这里比较了旧版本。

 http://zenka.net/roman/wordpress_memory_usage_comparison.png

蓝色是 WP 3.1,红色是 3.0.4 。新的 WP 更快,​​但也占用更多的内存。

这是一个包含文件的列表。

 http://zenka.net/roman/wordpress_3.1_vs_3.0.4_mem_by_file.png

这让我意识到 “一个一个 SEO 包” 中吃了多少内存 – 一个方法是使用插件的一小部分功能来获得我想要的东西。而且,我自己的插件似乎还是很糟糕的。

我想尝试在例如 comment.php(我不允许对我的博客发表评论) 和其他几个。我删除了所有已弃用的代码。我修剪了 kses.php,只能按需加载其全局表。我简化了 l10n(我没有本地化),使其函数立即返回字符串,无需查找。我仍然远离我任意设立的 30%的标记。

编辑:我下载并启用 APC 与默认设置 (32MB 的操作码缓存) 。这是比较:

 http://zenka.net/roman/3.1_without_with_apc.png

您可以看到代码加载大量加速,代码也占用更少的内存空间 (可能是因为我们只处理操作码而不是原始源) 。然而,内存消耗仍然相当高。

最佳解决方案

不值得的麻烦。 WordPress 不吃大量的内存 just-because 。它吃了很多内存,因为它运行着很多功能。

使用静态缓存插件来缓存结果 (页面生成) 更为简单和高效。这样大多数访客甚至不会打 WP 。

次佳解决方案

And this is why I think WordPress is
in serious need of a rewrite. You can
no longer blame its memory consumption
on sheer complexity of what it does.
It simply does things wrong.

一个天真的结论。阅读 Things You Should Never Do, Part I

谢谢你的内存使用情况。

稍后编辑:Automatic 已经发布了一个名为 prefork 的库,似乎可以做你所要求的:将 RAM 中的 WordPress 代码加载一次。

第三种解决方案

从 WordPress 3.2 开始,PHP 5.2 将是最低要求。我认为,在我们的腰带下,核心的一些可以开始重组,并使用与 auto-loading 的课程。这将让我们避免加载一些代码块,除非实际需要它们。例如,如果在页面浏览中没有嵌入或画廊,我们可能会避免加载大量的媒体代码。

然而,即使他们决定走这条路线,我也希望它是一个缓慢的进化 (像其他 under-the-hood 发生的变化) 。它将需要在许多文件和代码的位置周围进行洗牌,这可能会破坏一些插件的反向兼容性。

问题的一部分 (如果真的可以这样称呼) 就是没有这种条件加载,核心框架就不能提前知道为了生成内容视图而需要或不需要的功能。所以很多功能必须加载,以防万一他们需要。

第四种方案

How can we make WordPress initialize
its environment in memory only once,
and then reuse it many times for each
hit?

它叫做 opcode-caching 。

 http://en.wikipedia.org/wiki/PHP_accelerator

第五种方案

你可能不会减少 ram 的用法。但是,如果您使用 mod_php,则可能需要切换到 mod_fcgid

而 mod_php 稍慢,即使不需要加载 php,例如提供图像,静态文件,甚至缓存。如果你有很多的请求,这是很多的 ram 。

使用 fcgid 会减少这么多。

同样,使用静态缓存 (如 w3total 缓存) 将避免调用 php,这是一个非常好的优势:更少的 RAM 使用,更少的数据库连接。

第六种方案

哈。我现在正在开发一个网络应用程序,我完全打算超出我的共享托管帐户可以处理的数据和用法,所以我决定 – 虽然这将是非常容易构建在 WP – 尝试从 BackPress 工作作为一个框架,仅构建我需要的具体的 use-cases 框架。

所以我已经能够将我的核心环境从 WP 中的数百个 PHP 文件中减少到我实际需要的二十个,同时仍然能够利用所有的 db,HTTP,user-management,格式化和 cron 函数我喜欢 WordPress 。

问题是它的工作很多,我绝对不会相信我的 hackjob 超出我自己的个人用途。如果要使用完整的 WP 环境,请按原样进行操作。它是因为数以百计的开发商 fine-tuning 几年来一样好。像所有人都说过,通过找到一个更好的托管计划和研究缓​​存技术,你可以获得更多的东西,而不是通过黑客攻击核心来获得。

第七种方案

是的,WordPress 首先加载一切,然后做我们要求它做的事情。我可以回忆一下,我们可以在 RAM 中创建一个虚拟池,我们可以放入文件。我把这个想法放在了整个 WordPress 的记忆中 (< 10MB)&那么我们可以节省大量的 I / O,这个 I / O 单独应该提高速度。但是我从来没有机会去尝试,而且我也不是那么精通这样的东西。但这看起来值得一试。

第八种方案

几个基本建议:

  1. w3 缓存插件用于缓存
  2. 获取 memcache 安装和启用,也启用从 w3 总缓存设置 (操作码缓存是一个很好的选择,但它不太好,w3 总缓存插件)
  3. 最小化查询主题文件中的直接链接..
  4. 禁用所有额外的未使用的插件并删除。
  5. 优化数据库。

我正在运行一个知名的 wordpress 网站,每天巨大的流量.. 我不是专门的,甚至为我做的很好:)

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。