PHP/Apache的上限内存是多少?

25

当我运行我的PHP脚本时,我遇到了这个错误...

Fatal error: Out of memory (allocated 1827405824) (tried to allocate 88800 bytes)

我已经将这行代码添加到我的PHP脚本中...

ini_set("memory_limit","3000M");

这个语句似乎确实能够正确控制内存使用,但我似乎无法将其提高到大约1.8GB以上。就好像上限被限制在其他地方一样。我还添加了php.ini文件...

memory_limit = 3000M
有人知道内存是否受到其他限制吗?
我正在使用Xampp运行本地服务器。我的电脑是Windows 7,64位,有4GB的RAM。
我的脚本使用PHP的GD图像库,当试图使用ImageCreateTrueColor()函数分配一个图像引用时,出现了错误。
(我知道这是巨大的内存使用量 - 但这只是一个一次性脚本,这样做会更容易。)
谢谢。
更新....
@elusive @Orbling
我期望每个人都对这个问题厌烦了,但这里有简化后展示问题的代码。
<?php
    ini_set("memory_limit","4000000000");
    echo "ini_get = " . ini_get('memory_limit') . "<br>\n";
    echo "memory_get_usage = " . memory_get_usage(true) . "<br>\n";
    $bigImageHandle = imagecreatetruecolor(22200, 24800);  //this is line 5
?>

浏览器输出...

ini_get = 4000000000
memory_get_usage = 524288

Fatal error: Out of memory (allocated 1843396608) (tried to allocate 88800 bytes) in
E:\User\My_Webs\experiments\houseshunting\temp\osMaps\t1.php on line 5

我用少量的瓦片进行了测试,通过imagecreatetruecolor()使用的内存,我估计需要2.7GB。


我同意elusive的观点。你几乎肯定做错了什么,需要那么多的内存。 - DampeS8N
据我所知,GD将小图像之一的内容复制到大图像上。您应该能够在复制后释放小图像的内存。您可以逐个图像地执行此操作,并减少同时使用的总内存。大图像本身没有问题,因为它在内存中只有约88KB。问题在于(显然)同时存在于内存中的大量小图像。 - jwueller
@elusive 好的,我会在另一个“回复”中发布我的代码,而不是评论。不知道最好的方法是什么 - 我真的不想回答自己的问题? - spiderplant0
@elusive - 就好像imagecreatetruecolor()函数会分步骤地分配内存一样,因为据我所见,所有1.7GB的内存都是由imagecreatetruecolor函数分配的。$bigImageHandle = imagecreatetruecolor($tileWidth * $bigImageTilesX, $tileHeight * $bigImageTilesY); - spiderplant0
@elusive 一旦创建了大图像,它将被发送到GIS软件进行地图重投影,然后将其拆分为256 * 256的谷歌地图瓦片。由于重投影导致图像变得“非正方形”,因此将其分成阶段并尝试创建瓷砖将会很困难。即使我将其拆分,图像仍然会很大。 - spiderplant0
显示剩余10条评论
10个回答

12

使用Acquia Dev Desktop时,我遇到了许多内存限制崩溃问题。

在将内存限制增加到PHP.ini之后。

php_value memory_limit                  1024M
php_value max_execution_time            3000

这个问题出现的频率较低,但仍然存在(特别是在重新创建功能时)。

我在我的httpd.conf文件中将StackThread增加到16M。

ThreadStackSize 16*1024*1024

它解决了内存崩溃问题。希望能帮到您。


似乎解决了我的问题(Win7,64位,xampp)对于这个错误消息:VirtualAlloc()失败:[...] VirtualFree()失败:[...] [...] PHP致命错误:内存不足(分配98566144)(尝试分配16384字节)[...] - Sven

9
您正在使用64位操作系统,但Apache和PHP很可能仍然是32位的。如果您使用mod_php,则这里的限制因素是apache。
32位进程的RAM限制约为2GiB,除非您使用了/3GB开关并且软件知道3GB支持。
这仍然留下大约200 MiB似乎没有使用,但它足够小,可以被各种库使用,所有库都必须加载到内存中。
据我所知,库使用情况不会显示在承诺的内存中,但仍计入2GiB限制(就像设备内存计入32位Windows上的4GiB限制一样。安装2 GiB显卡将使可用RAM降至2GiB以下)。
最可能的解决方案?安装64位PHP,然后将其分派给该(使用system()调用,也许)。

2
在Ubuntu 18.04中,
检查PHP版本:php -v
在我的情况下,我有PHP 7.4
编辑文件:nano /etc/php/7.4/apache2/php.ini
搜索并更改memory_limit = 2048M
编辑文件:nano /etc/php/7.4/cli/php.ini
搜索并更改memory_limit = 2048M
最后:systemctl restart apache2

1
检查您的Apache配置文件(例如httpd.conf)。很可能有一个RLimitMEM指令限制了处理请求的子进程允许使用的内存。
因此,如果Apache生成带有内存限制的进程,则无论您如何设置PHP限制,都不能超过该限制。
如果您在托管服务上并且拥有共享服务器,则很可能无法访问此配置文件,并且需要与提供商合作。正如您所看到的,这是适用于整个服务器的配置...您不太可能让他们更改此配置。然而,如果您正在寻求生成大于1.5Gig进程,那么您应该以其他方式解决问题(其他人已经建议过)或获取某种专用服务器(例如EC2)。
例如:
/usr/local/apache/conf
#RLimitMEM 85643200 104857600   # Limit to: 80Mb / process, 100Mb total
RLimitMEM 134217728 537395200   # Limit to: 128Mb / Process, 512Mb total

1
问题可能是由于运行32位的Apache和PHP引起的。尝试升级为64位二进制文件,看看是否解决了问题。

1
你正在使用哪个PHP版本?
memory_limit变量是或曾经包含在32位整数中,因此不能超过2GB。
参见:http://bugs.php.net/bug.php?id=39132&edit=1 从该错误报告的底部评论中可以看出,可能是将人类可读形式转换为数字的例程,尝试将其放入数字中。

我假设你有可用的内存?你尝试过在php.ini中设置它吗? - Orbling
是的,我在两个地方都尝试过了。我有4GB的物理内存。根据任务管理器,在运行脚本之前已经使用了44%的内存(虽然由于Windows Superfetch很难说)。不过我认为如果内存不足,它只会使用页面文件缓存,对吧? - spiderplant0
嗯,如果内存将成为问题,那你打算如何处理这张图片?错误信息表明你已经在PHP中分配了大约1.8GB的RAM。 - Orbling
我以为 PHP 应该允许我使用 4GB。我不明白为什么它在只使用了 1.7GB 后就出现了错误。1827405824 + 88800 < 4GB(也远小于2GB)。 - spiderplant0
32位应用程序无法使用4GB的内存,除非它们被编译为知道额外可用空间的应用程序(设置/LARGEMEMORYAWARE标志),否则它们主要限制每个进程2GB。然后PHP本身将有相当大的开销,这可能会导致下降到1.7-0.8GB。 - Orbling
显示剩余4条评论

0

我曾经遇到过完全相同的问题,经过大量搜索后,我发现这与内存限制无关,而是我的代码中存在一个错误:我有一个使用数组的函数,位于外部文件中。在这个函数中,我将数组设置为“全局”,但忘记了包含该数组的文件....就像spiderplant0的错误一样,这给了我一个非常巨大的内存分配错误。 因此,请检查您的代码,并尝试查看哪个部分创建了此错误。


-2

试试这个

set_time_limit(300);
ini_set('memory_limit', '20000M');

3
你有没有注意到你建议使用20吉字节?这应该如何运作? - jwueller
@jwueller 它应该像魔法一样工作。 - Serge Velikan

-2

试试这个:

#php_value memory_limit 300M 
#php_value upload_max_filesize 200M 
#php_value post_max_size 200M 
#php_value max_execution_time 80000 
#php_value max_input_time 80000   

我应该把这些代码放在哪里?互联网搜索建议放在 .htaccess 文件中,但是我在 xammp 文件夹中找不到这个文件。 - spiderplant0
3
你为什么要加上 # 呢? - jwueller
我没有 .htaccess 文件,应该在哪里创建这个文件? - spiderplant0
在php.ini文件中添加以下内容: upload_max_filesize=200M memory_limit=300M upload_max_filesize=200M post_max_size=200M max_execution_time=100000 max_input_time=100000 - Pradeep Singh
谢谢Pradeep Singh。但是,为什么是300M等等?你的意思是3000M吗? - spiderplant0
@Pradeep Singh - 将内容粘贴到php.ini底部并重新启动服务器。但是没有任何变化。 - spiderplant0

-4
尝试使用 ini_set('memory_limit', '-1');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接