【问题标题】:PHP Fatal error: Allowed memory size of 268435456 bytes exhaustedPHP致命错误:允许的内存大小为268435456字节已用尽
【发布时间】:2012-04-24 19:39:03
【问题描述】:

我一直看到内存耗尽错误

PHP 致命错误:允许的内存大小为 268 435 456 字节已用完

在我的日志文件中。

即使服务器负载非常轻且无法在本地主机上重现,此错误也会随机出现。我有一个来自 hostgator 的 VPS 4 服务器,负载为 MB。 php 配置允许高达 256 Mb。

代码如下

function func_select_array($qry)
{
    $i=0;
    $data=array();
    $qry_result=mysql_query($qry);

    if($qry_result)
    {
        while ($row=mysql_fetch_assoc($qry_result))
        {
            $data[$i] = $row;
            $i++;
        }
        return $data;
    }
    else 
    {
      return 2;
    }
}


    function func_check_rule_out_bid($auc_id,$bid_amount,$return_freq,$recheck)
    {
        $bid_qry="select * from tbl_bid where ubaid='".$auc_id."' and ubf='1' order by uba desc limit 0,10";
        $bid_array=func_select_array($bid_qry);
    }

表 tbl_bid 有 2800 条记录。 我在 func_select_array 函数内的 while 循环中出现内存耗尽错误。 我无法想象这个查询需要 256M+。它似乎不是php问题,而是mysql中的问题。请帮忙...

【问题讨论】:

  • 您在哪一行得到错误。并且放心,是和PHP有关的,不是mysql的。如果是 mysql,则服务器不会返回结果。但是您应该验证您是否发送了正确的查询。
  • 2800 条记录可能没问题。每条记录的大小是多少?它们是否包含BLOBs?
  • 首要任务是重新创建错误。做不到这一点,记录一切。如果可能,在内存耗尽之前记录查询、mysql_num_rows()memory_get_peak_usage() 的结果以及其他任何内容。然后,下次它发生时,您可以查看它尝试迭代的查询和记录数。您可能会发现一些您通常不会想到的东西。
  • 您确定没有从其他地方调用 func_select_array 吗?还是因为某种原因很多次?
  • 您执行select * from tbl_bid 这意味着,如果有一个包含大量数据的字段(MySQL 中的单个字段可能是 TB 大),并且您将其填充到 PHP 的内存中 - 好吧,你可以达到一个极限。这是完全正常的,取决于您查询的数据量。

标签: php mysql fatal-error


【解决方案1】:

内存耗尽可能很难调试,因为错误只告诉您内存最终用完的位置,而不是大部分内存的使用位置。

您可以使用内存分析器(例如 Xdebug 中的那个)来查找所有内存的去向。

【讨论】:

    【解决方案2】:

    您应该对查询使用 EXPLAIN。确保您没有进行繁重的查询(乍一看似乎没有)。

    第二种方式,可能是你得到了一些太重的 BLOB ot TEXT 字段。不是在你当地,这就是为什么你不能在当地环境中得到这个。

    确保您没有遇到无限循环。可以吗?

    使用跟踪 php 错误并尝试/​​捕获此块以获得有关错误的更好信息。

    try {
            while ($row=mysql_fetch_assoc($qry_result))
            {
                $data[$i] = $row;
                $i++;
            }
    
    } catch (Exception $e) {
       debug_print_backtrace(); 
       var_dump($e->getMessage());
    }
    

    【讨论】:

    • 你好。查询量不大。该表有 11 列(5 个整数、4 个 varchars(255)、1 个日期时间和 1 个双精度)。我不认为我进入了无限循环,因为这是查询在大多数情况下都做得很好。内存错误是随机出现的。同样在调用函数中,我将行数限制为 10。那么,如果始终迭代 10 行,而不管表中的记录数如何,怎么会有问题呢?您能告诉我如何尝试捕获并记录导致内存错误的查询吗?
    • 除了你可以打印你的查询,看看有没有什么奇怪的地方。
    猜你喜欢
    • 2017-11-06
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    • 2014-03-07
    • 2014-02-07
    • 2014-09-27
    相关资源
    最近更新 更多