【问题标题】:Allowed memory size of 8589934592 bytes exhausted允许的内存大小为 8589934592 字节已用尽
【发布时间】:2018-02-24 12:06:05
【问题描述】:

我在 Laravel 的日程安排上遇到了问题。

我发现有关于此错误的重复问题,但这些问题并不能解决我的问题

root@trafficshield:/var/www/vhosts/trafficshield.tools/httpdocs# /opt/plesk/php/7.1/bin/php artisan schedule:run 运行调度 命令:关闭 ^[[15~PHP 致命错误:允许的内存大小为 8589934592 字节用尽(试图分配 4096 字节) /var/www/vhosts/trafficshield.tools/httpdocs/vendor/laravel/framework/src/Illum inate/Database/Eloquent/Model.php 第 279 行 PHP

此时间表旨在统计所有活动对我们服务的访问次数。

    $schedule->call(function () {
        $campaigns = Campaign::all();
        foreach ($campaigns as $campaign) {
            $campaign->denied_visits = $campaign->visitsDenied->count();
            $campaign->allowed_visits = $campaign->visitsAllowed->count();
            $campaign->save();
        }
    })->everyFiveMinutes();

如何更改 PHP 代码以避免此问题?

配置:memory_limit : 8G

提前感谢您的帮助。

【问题讨论】:

  • 更改memory_limit 将是一个临时修复,当数据量增加时问题又回来了,所以我建议你避免使用 Elloquent 来完成这项工作,因为 Elloquent 的内存效率很差。我会给你一个方法坚持
  • 深思熟虑:如果陷入无限循环,您经常会耗尽内存...
  • @Greg 我确定没有无限循环。

标签: php postgresql laravel


【解决方案1】:
Allowed memory size of 8589934592 bytes exhausted

这种错误是由于内存中的数据量很大,所以修复它的方法是编写一个不太重的内存脚本。通过更改memory_limit,我们只能得到临时修复,因为当我们的数据增长时它会回来。

    $campaigns = Campaign::all(); //at this point you are pulling the whole Campaigns table to memory.. and you pull some extra rows after that increasing even more the memory use

正如我所说,Elloquent 在执行此类任务时效率很低,所以让我们像 mysqli 过去那样,一一获取数据库行:

  $db = DB::connection()->getPdo(); //get a database connection instance

  $main_query_sql = "SELECT * FROM Campaigns"; //write our query 
  $main_query = $db->prepare($main_query_sql); //prepare it to get executed
  $main_query->execute(); //execute our query


  $visits_denied_sql = "SELECT COUNT(*) as total FROM VISITS WHERE DENIED = 1 AND CAMPAIGN_ID ="; //let's prepare our aggregate queries

  $visits_allowed_sql = "SELECT COUNT(*) as total FROM VISITS WHERE DENIED = 0 AND CAMPAIGN_ID ="; //I just assumed them so change it as you need

  $visits_denied = null;
  $visits_allowed = null;

  while($campaign = $main_query->fetch()){ //fetch our rows one by one
      //now we are getting an associative array from the db instead of a model so we cannot use it as a Laravel Model (we can't use ->save() method or eager loading)
      $visits_denied = $db->prepare($visits_denied_sql.$campaign['id']);
      $visits_denied = $visits_denied->execute();
      $denied_visits = $visits_denied->fetch();

      $visits_allowed= $db->prepare($visits_allowed_sql.$campaign['id']);
      $visits_allowed= $visits_allowed->execute();
      $allowed_visits = $visits_allowed->fetch();

      $campaign['denied_visits'] = $denied_visits['total'];
      $campaign['allowed_visits'] = $allowed_visits['total'] ;

      //edit with the correct update sentence:
      $insert_query_sql = "UPDATE CAMPAIGNS SET allowed_visits = :visits_allowed, denied_visits = :visits_denied WHERE id = :id";
        $insert_query = $db->prepare($insert_query_sql);
        $insert_query->bindParam(':visits_allowed', $campaign['allowed_visits']);
        $insert_query->bindParam(':visits_denied', $campaign['denied_visits']);
        $insert_query->bindParam(':id', $campaign['id']);
        $insert_query->execute();

  }

在你的日程安排中试试这个,如果有效,请告诉我!

【讨论】:

  • 我有一个错误:puu.sh/xAgsa/f248b8b553.png,我使用的是 Laravel 5.3 和 PostgreSQL
  • 你是这样导入的吗? use Illuminate\Support\Facades\DB;
  • 是的,我导入了它!
  • 也许你导入了不正确的,我有一个使用类似代码的生产项目。检查sql语法可能是错误的。并使用php artisan schedule:run -vvv 标志获取有关错误的更多信息
  • 是的,正如我所说,我只是假设您的表结构和列,根据需要修复查询
猜你喜欢
  • 2012-08-29
  • 2020-10-06
  • 2012-08-08
  • 1970-01-01
  • 2017-08-26
  • 2019-10-05
  • 2015-10-13
  • 2011-04-23
  • 1970-01-01
相关资源
最近更新 更多