近日在升级wordpress 3.2.1和若干插件的过程中,发现了一个wordpress的错误:Allowed memory size of XXX bytes exhausted
Fatal error: Allowed memory size of 25165824 bytes exhausted (tried to allocate 150 bytes) in [Blog root path]/wp-includes/pomo/mo.php on line 206
通过搜索网络和请教牛人,发现能够得出来的错误类型原因和解决方案基本上只有几种:
有几种类似的报错信息:
- Fatal error: Out of memory (allocated 28835840) (tried to allocate 3981531 bytes) in [Blog root path]/wp-includes/class-http.php on line 1426
- (similar message) in [Blog root path]/wp-admin/admin.php on line 40
- (similar message) in [Blog root path]/wp-admin/includes/media.php on line 268
- Fatal error: Out of memory (allocated 49545216) (tried to allocate 77824 bytes) in /home/xxxxx/public_html/xyz/admin.php(1758) on line 40
- Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 147555 bytes) in [Blog root path]/wp-includes/wp-db.php on line 97
从表面上看这类报错均是由于内存不够用导致的,但是究竟是什么导致了原本运行的很好的程序突然变成这个样子呢?(或者你是在新安装一个wordpress)
我查看了一下官方网站的Requirements大体如下:
3.2版本的WP需要PHP5.2.4或更高,MySQL5.0或更高,需要运行Apache或者Nginx做Web请求服务。
To run WordPress your host just needs a couple of things:
The requirements have changed as of WordPress 3.2. The minimum requirements for WordPress 3.1 are PHP 4.3 and MySQL 4.1.2.
That’s really it. We recommend Apache or Nginx as the most robust and featureful server for running WordPress, but any server that supports PHP and MySQL will do. That said, we can’t test every possible environment and each of the hosts on our hosting page supports the above and more with no problems.
估算了一下,要运行这几个服务的话,最低需要70M 以上的内存,一般的主机或者空间提供商都是预先跑起来这些服务以后额外给你的php程序再提供最少16M 的内存的(要是更大的话几个G 的也有,当然不是免费的:P),经测试,wordpress在locahost上跑起来的时候占用了大约11.5M左右的内存空间,也就是说,精简安装的情况下,wordpress在很少的内存下也可以运行起来,而本人的主机提供商提供了32M 的内存空间,并且在升级wordpress之前一直运行稳定,未出现过memory问题,并且要特别提到的一点是,我的wordpress上安装了21个插件,也占用不少内存。
接下来先来看看网络上的解决方法吧:
方法一:You can even consider adding a line in .htaccess file which will resolve the issue.
php_value memory_limit 256M
就是在 .htaccess 文件中加上红色的那行字
方法二:Add this to your wp-config.php file:
define ('WP_MEMORY_LIMIT', '256M' );
在你的 wp-config.php 文件中加上红色的那行字
方法三:wp-settings.php,编辑这个文件,修改
define('WP_MEMORY_LIMIT', '32M');
为
define('WP_MEMORY_LIMIT', '256M');
方法四:在你的博客目录中添加一个 php.ini 文件,并且写入下面那行
memory_limit=256M
方法五:其实是方法四升级版:在你的博客目录中添加一个 php.ini 文件,并且写入下面的内容
register_globals=Off safe_mode=off magic_quotes_gpc=On allow_url_include=Off file_uploads=on memory_limit=256M max_executi alt=90 post_max_size=10M upload_max_filesize=10M max_input_time=300
以上列举了很多方法,到底有没有用呢? 逐一分析并尝试:
方法一:
htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。
通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
我们在此将php的memory的限制手动改为 256M大小,其实就是提高我们的php程序分配的运行时内存空间,但是有没有效果呢?
在一定情况下可能会有效果,因为这样写跟写在配置文件中的效果其实是一样的,但是有的主机供应商可能会刻意屏蔽掉htaccess的功能。
方法二、方法三:
都是在wordpress的配置文件中提高我们的php程序分配的运行时内存空间,但是有可能会有个疑问,假如我的主机供应商只给我32M的空间我在这里设置有用么?其实这里设置的大小跟主机供应商给你提供的大小没有太多的对应关系。举个例子,就像在只有1G 物理内存的情况下,你仍然可以运行占用2G 内存的程序一样,这里设置的差不多是逻辑上可以使用的内存大小的意思,但是,有个问题要注意,如果物理内存比较小而需要的比较多的话,系统可能会因为频繁的页置换导致系统的颠簸,也有可能主机资源管理控制软件回把你的这堆进程kill掉。(后面这段不懂无所谓,也是因不同的主机而定)
另外:在PHP5.2.3-win32这个版本有个bug,PHP对于内存的分配有泄漏的情况
当你分配一个较大的内存空间时,他无法正确编址 链接地址
PHP Fatal error: Out of memory (allocated 1048576) (tried to allocate 393216 bytes)
PHP Fatal error: Out of memory (allocated 1048576) (tried to allocate 393216 bytes)
PHP Fatal error: Out of memory (allocated 1048576) (tried to allocate 393216 bytes)
PHP Fatal error: Out of memory (allocated 1048576) (tried to allocate 393216 bytes)
PHP Fatal error: Out of memory (allocated 786432) (tried to allocate 393216 bytes)
PHP Fatal error: Out of memory (allocated 1310720) (tried to allocate 393216 bytes)
方法四、方法五:
这个php.ini 是php环境中最正统的设置文件,他这里的设置也是提高我们的php程序分配的运行时内存空间。
但是:一般的php空间的话,管理员是不会开放整个php 运行环境的配置权限给你的,另外管理员还有可能强制指定整台主机的配置文件只使用/etc/php/apache2-php5.3/php.ini (这个路径可能不太一样,本人本地计算机是一台Gentoo+php5.3+apache2+mysql的机器)。所以也不一定起作用。
另外这样设置完成后,还需要将环境变量重置一下,
SetEnv PHPRC [Blog root path]/php.ini
但是要执行这条指令,一般的空间也是没有办法的,除非你是VPS。:)
============================================================================
分割一下:如果上面的方法已经解决问题了可以不用向后看了,后面是深层次原因
============================================================================
我们从程序这边找找问题,是不是可以得到改善。就从这行代码开始看吧。wp-includes/pomo/mo.php on line 206
经过查看,我得出了一个结论,这个出错的文件属于多国语言翻译的功能中的一块,主要负责的是英文转换成其他语言然后在后台管理界面中显示翻译后的内容。比如常见的wordpress中文版。
function Translation_Entry($args=array()) {
// if no singular — empty object
if (!isset($args[‘singular’])) {
return;
}
// get member variable values from args hash
foreach ($args as $varname => $value) {
$this->$varname = $value;
}
if (isset($args[‘plural’])) $this->is_plural = true;
if (!is_array($this->translations)) $this->translations = array();
if (!is_array($this->references)) $this->references = array();
if (!is_array($this->flags)) $this->flags = array();
}
可以看到我在图上标注出来的这一小段代码这段代码的意思是在翻译后的文件中取出翻译好的字符串,在显示时替换掉原来的英文,foreach是枚举每一个字符串变量。
接着看翻译后的文件是什么样子的:
截图链接
可以看出,这个文件有599行,383747byte。共3313条记录,在本机上,单单使用vim打开该文件时,MEM%占用达到0.4%,本人使用的电脑为4G 内存,也就是说只是打开该文件时就需要占用掉16M左右的内存,此时还没有对这个文件中的字符串解析和替换,相信在进行这一系列操作时,占用会更多。
可以得出来一个结论:WordPress是个吃内存大户,尤其是中文版的wordpress,那如何解决呢?
解决:
当你升级后发现进不去后台了,那就尝试登录ftp,将wp-content/languages/ 下的文件删光,尝试下是不是可以了?
当然,如果还是进不去的话,最好是将wp-content/plugins,目录改个名字,即禁用掉了所有的插件,这样的话,应该内存占用会变得非常少。
如果还是不可以的话,请留言吧,可以一起讨论一下:)
PS:
1.发现了wordpress中文翻译中,并不是按需进行字符串替换的,如能将此函数改为按需替换显示的话,相信能够大幅减少用于翻译的内存和CPU占用。
2.解决wordpress 内存占用问题的关键是如何让你的wordpress合理使用内存,而不是越大越好,当然,如果能够联系空间提供商扩大内存解决问题的话也是非常好的一种方法:)如果想省钱解决问题的话,就是采用英文版的wordpress不也是很好的吗:)
3.正在看wordpress的一部分可能设计到权限提升的代码,阅读得不是非常明白,但是感觉有逻辑漏洞存在,可能会是一个后台提权BUG。
4.写的比较仓促,错别字和表达不妥的地方还请大家指出。
coolfire同学提出了一种类似的方法,跟方法三方法四异曲同工:
在网站根目录(public_html)下创建一个文件php.ini,里面添加下面的代码:
memory_limit = 64M然后编辑同目录下的.htaccess文件,在文件末尾添加以下代码:
suPHP_ConfigPath /home/username/public_html/用你控制面板的用户名替换username,支持问题即可解决。
原创文章,转载请注明
出处:http://www.cnblogs.com/huangcong/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。