Lavarel Eloquent ORM常驻进程下的内存溢出问题

Laravel 的 Eloquent ORM 提供了漂亮、简洁的 ActiveRecord 实现来和数据库交互。每个数据库表都有一个对应的「模型」用来与该表交互。你可以通过模型查询数据表中的数据,并将新记录添加到数据表中。

业务里使用了ORM来进行数据库操作,有个cron运行一段时间后就报内存溢出的错误,之前一直没时间彻底解决,这次有时间彻底搞清楚了。

代码类似:

$capsule = new Capsule;

foreach ($database[$env] as $name => $conf) {
    // 创建链接
    $capsule->addConnection($conf, $name);
}

// 设置全局静态可访问
$capsule->setAsGlobal();

// 启动Eloquent
$capsule->bootEloquent();

while (1) {
    try {
        $service = new PostModel();
        $dataList = $service->where('status', 1)->limit(100)->get()->toArray();
    } catch (Exception $e) {
        continue;
    }

    if (!$dataList) {
        break;
    }

    foreach ($dataList as $data) {
        // do something
        // 最后会更新status字段=2
    }
}

断点调试,发现每查询一次数据,内存就会增长3M左右,运行30次左右,就会报内存溢出。
怀疑是不是ORM这里会记录每次的查询结果,搜索了一下,发现还真有类似功能。
Laravel Eloquent display query log

最终实现代码:

$capsule = new Capsule;

foreach ($database[$env] as $name => $conf) {
    // 创建链接
    $capsule->addConnection($conf, $name);
    // 关闭查询日志,常驻进程会导致内存溢出
    $capsule->getConnection($name)->disableQueryLog();
}

// 设置全局静态可访问
$capsule->setAsGlobal();

// 启动Eloquent
$capsule->bootEloquent();

while (1) {
    try {
        $service = new PostModel();
        $dataList = $service->where('status', 1)->limit(10)->get()->toArray();
    } catch (Exception $e) {
        continue;
    }

    if (!$dataList) {
        break;
    }

    foreach ($dataList as $data) {
        // do something
        // 最后会更新status字段=2
    }
}

标签: PHP, lavarel

添加新评论