在PHP中导致“无法为池分配内存”的原因是什么?

时间:2010-09-16 02:33:44

标签: php caching memory apc

我偶尔遇到服务器的内存分配限制,特别是对于像Wordpress这样臃肿的应用程序,但从未遇到“无法为池分配内存”,并且无法跟踪任何信息。

有谁知道这意味着什么?我试过增加memory_limit但没有成功。我还没有对该应用程序进行任何重大更改。有一天没有问题,第二天我遇到了这个错误。

12 个答案:

答案 0 :(得分:123)

使用TTL为0意味着APC将在内存不足时刷新所有缓存。该错误不再出现,但它使APC的效率低得多。没有风险,没有麻烦,“我不想做我的工作”的决定。 APC并不意味着以这种方式使用。您应该选择足够高的TTL,以便访问最多的页面不会过期。最好的是提供足够的内存,以便APC不需要刷新缓存。

请阅读手册以了解如何使用ttl:http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

解决方案是增加分配给APC的内存。 通过增加apc.shm_size来执行此操作。

如果编译APC以使用共享段存储器,您将受到操作系统的限制。键入此命令以查看每个段的系统限制:

sysctl -a | grep -E "shmall|shmmax"

要分配更多内存,您必须使用参数apc.shm_segments增加段数。

如果APC正在使用mmap内存,那么你没有限制。内存量仍由相同的选项apc.shm_size定义。

如果服务器上没有足够的内存,请使用filters选项来防止缓存较少访问的php文件。

但永远不要使用0的TTL。

正如c33s所说,使用apc.php检查你的配置。将文件从apc包复制到web文件夹并将浏览器指向它。您将看到真正分配的内容及其使用方式。图表必须在数小时后保持稳定,如果它们在每次刷新时完全更改,则表示您的设置错误(APC正在刷新所有内容)。分配比APC真正用作安全边际的公羊多20%,并定期检查。

仅允许32MB的默认值非常低。 PHP是在服务器为64MB且大多数脚本每页使用一个php文件时设计的。如今,像Magento这样的解决方案需要超过10k个文件(APC中约为60Mb)。你应该允许足够的内存,所以大多数PHP文件总是被缓存。这不是浪费,将操作码保存在ram中更有效,而不是在文件缓存中使用相应的原始php。 现在我们可以找到具有24Gb内存的专用服务器,每月只需80美元,所以不要犹豫,允许几个GB到APC。我在托管5Magento商店和~40 wordpress网站的服务器上放入24GB的2GB,APC使用1.2GB。对于Magento安装计算64MB,对于带有一些插件的Wordpress计算40MB。

此外,如果您在同一台服务器上有开发网站。从缓存中排除它们。

答案 1 :(得分:89)

<强> Probably is APC related.

对于遇到此问题的人,请指定.ini设置。特别是你的apc.mmap_file_mask设置。

对于文件支持的mmap,应将其设置为:

apc.mmap_file_mask=/tmp/apc.XXXXXX

要直接从/ dev / zero mmap,请使用:

apc.mmap_file_mask=/dev/zero

对于符合POSIX标准的共享内存支持的mmap,请使用:

apc.mmap_file_mask=/apc.shm.XXXXXX

答案 2 :(得分:36)

我的解决方案:

  • apc.ttl = 0
  • apc.shm_size =您想要的任何内容

编辑开始

警告!

@bokan告诉我,我应该在这里添加警告。

如果您的ttl为0,则表示可以立即清除每个缓存的项目。因此,如果你有一个像2mb这样的小缓存大小和ttl为0,这会使apc变得无用,因为缓存中的数据总是被覆盖。

降低ttl意味着缓存不能变满,只能使用无法替换的项目。

所以你必须在ttl和缓存大小之间选择一个很好的平衡。

就我而言,我的缓存大小为1gb,所以对我来说已经足够了。

编辑结束

在使用php 5.2.17的centos 5上有同样的问题,并注意到如果 缓存大小很小,而ttl参数是“高”(如7200) 有很多PHP文件要缓存,然后缓存填满相当快 并且apc没有找到它可以删除的任何内容,因为所有文件都在 缓存仍然适合ttl。

增加内存大小只是一个部分解决方案,你仍然可以运行 如果缓存填满并且所有文件都在ttl中,则会出现此错误。

所以我的解决方案是将ttl设置为0,所以apc填满了缓存 总而言之,apc有可能为新事物清除一些记忆 数据

希望有所帮助

编辑: 另见:http://pecl.php.net/bugs/bug.php?id=16966

下载http://pecl.php.net/get/APC提取并运行apc.php,你有一个很好的图表,你的缓存使用情况如何

答案 3 :(得分:6)

运行apc.php脚本是了解问题所在的关键,IMO。这有助于我们正确调整缓存大小,目前似乎已经解决了这个问题。

答案 4 :(得分:4)

对于像我这样的新手,这些资源有所帮助:

查找apc.ini文件以进行上述c33s建议的更改,并设置建议的金额: http://www.untwistedvortex.com/optimizing-tuning-apc-alternate-php-cache/

了解apc.ttl是什么: http://www.php.net/manual/en/apc.configuration.php#ini.apc.ttl

了解apc.shm_size是什么: http://www.php.net/manual/en/apc.configuration.php#ini.apc.shm-size

答案 5 :(得分:4)

正如Bokan所提到的那样,如果可以的话,你可以提高记忆力,而且他对TTL为0的反制效率是正确的。

注意:这就是我为特定问题修复此错误的方法。它是一个通用的问题,可能是由分配引起的,所以如果你得到错误并且你认为它是由重复的PHP文件加载到APC引起的,那么只需遵循下面的内容。

我遇到的问题是当我发布我的PHP应用程序的新版本时。即用新的替换所有我的.php文件AP​​C会将两个版本加载到缓存中。

因为我没有足够的内存用于两个版本的php文件AP​​C会耗尽内存。

有一个名为apc.stat的选项告诉APC检查某个特定文件是否已更改,如果是这样,则替换它,这通常可以用于开发,因为您不断进行更改,但是在生产时它通常会被关闭,因为它是在我的情况下 - http://www.php.net/manual/en/apc.configuration.php#ini.apc.stat

启用apc.stat将解决此问题,如果您对性能命中率没有问题。

我为我的问题提出的解决方案是检查项目版本是否已更改,如果是,则清空缓存并重新加载页面。

define('PROJECT_VERSION', '0.28'); 

if(apc_exists('MY_APP_VERSION') ){

    if(apc_fetch('MY_APP_VERSION') != PROJECT_VERSION){
        apc_clear_cache();
        apc_store ('MY_APP_VERSION', PROJECT_VERSION);
        header('Location: ' . 'http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']);
        exit;  
    }

}else{
    apc_store ('MY_APP_VERSION', PROJECT_VERSION);
}

答案 6 :(得分:2)

这适用于我们的人(在同一台服务器上运行大量Wordpress站点)。

在/etc/php.d/apc.ini文件中更改了内存设置。它被设置为64M,因此我们将其翻倍至128M。

apc.shm_size = 128M

答案 7 :(得分:1)

观察互联网可能有各种原因。 在我的情况下,除了......之外,一切都是默认的。

apc.shm_size = 64M

......清除了我早些时候发出的无数警告。

答案 8 :(得分:1)

在将OpenCart安装移动到其他服务器后,我收到错误“无法为池分配内存”。我也尝试过提高memory_limit。

在我更改了错误消息中文件的权限后,错误停止了,以便用户具有apache运行的写访问权限(apache,www-data等)。我没有直接修改/ etc / group(或将文件chmod到0777),而是使用了usermod:

usermod -a -G vhost-user-group apache-user

然后我不得不重新启动apache才能使更改生效:

apachectl restart

或者

sudo /etc/init.d/httpd restart

或者系统用来重启apache的任何内容。

如果网站位于共享主机上,您可能必须使用FTP程序更改文件权限,或者与托管服务提供商联系?

答案 9 :(得分:1)

要解决此问题,请将apc.shm_size的值设置为整数 找到您的apc.ini文件(在我的系统apc.ini文件位置/etc/php5/conf.d/apc.ini中)并设置: apc.shm_size = 1000

答案 10 :(得分:1)

在我的系统上我必须插入 apc.shm_size = 64M 到/usr/local/etc/php.ini (FreeBSD 9.1) 那时我看了apc.php(我从/usr/local/share/doc/APC/apc.php复制到/ usr / local / www / apache24 / data) 我发现缓存大小已从默认的32M增加到64M,而且我不再获得大量缓存全部计数

的引用: http://au1.php.net/manual/en/apc.configuration.php 还阅读了Bokan的评论,他们非常乐于助人

答案 11 :(得分:0)

监控您的缓存文件大小(您可以使用apc pecl包中的apc.php)并增加 apc.shm_size根据您的需要。

这解决了这个问题。