我该如何解决这个学说记忆问题

时间:2014-03-12 17:49:04

标签: php symfony doctrine-orm doctrine

以下代码遍历一个包含~1,000,000行的表。我被建议使用Doctrine的iterateResult()方法来避免内存问题(docs):

$batchSize = 1000;
    $i = 0;
    $q = $em->createQuery('SELECT i from MyBundle:Items i WHERE i.imgSize IS NULL');

    $results = array();

    $iterableResult = $q->iterate();
    while (($row = $iterableResult->next()) !== false) {

        $results[]=$row[0];
        $em->detach($row[0]);

        if (($i % $batchSize) === 0) {

            $em->clear(); // allegedly detaches all objects from Doctrine!
            $this->chunkedWhereCallback($results);

        }
        ++$i;
    }

即使我将批量大小设置为1,上面的代码也会超出允许的内存。如果我将查询更改为读取SELECT i.id, i.img FROM MyBundle:Items i WHERE i.imgSize IS NULL,则内存错误不存在但是我的$ row数组没有[0]关键例如:

array(1) {
  [5926] =>
  array(2) {
    'id' =>
    int(12794)
    'img' =>
    string(57) "http://some/url/1203/104962420.jpg"
  }
}

有人能告诉我这里缺少什么吗? Laravel的Eloquent处理这个操作很好,但我想将代码移植到Doctrine / Symfony2。我已经尝试将php内存限制设置为1024M,这应该足够多,并且比我在服务器上可用的更多。

Memory error is Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried to allocate 32 bytes) in /Users/mre/Sites/ site/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php on line 699

1 个答案:

答案 0 :(得分:0)

我也遇到了同样的问题,我不完全确定它是Doctrine的问题,这似乎是PHP本身的一个问题。

无论如何,我发现解决方案是强制PHP的垃圾收集如下:

$batchSize = 1000;
$i = 0;
$q = $em->createQuery('SELECT i from MyBundle:Items i WHERE i.imgSize IS NULL');

$results = array();

$iterableResult = $q->iterate();
while (($row = $iterableResult->next()) !== false) {

    $results[]=$row[0];
    $em->detach($row[0]);

    if (($i % $batchSize) === 0) {

        $em->clear(); // allegedly detaches all objects from Doctrine!
        // Force PHP's GC
        gc_collect_cycles();
        $this->chunkedWhereCallback($results);

    }
    ++$i;
}

gc_collect_cycles的调用应释放内存并防止可用内存耗尽。