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



以下代码在具有约1,000,000行的表上迭代。建议我使用学说的iterateresult()方法来避免记忆问题(文档):

$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,则不存在内存错误,但是我的$行阵列没有[0]键,例如:<:

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

有人可以告诉我我在这里缺少什么吗?Laravel的雄辩处理此操作很好,但我想将代码移植到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

我也遇到了同样的问题,我不确定这是学说的问题,这似乎是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应释放内存并防止可用内存的耗尽。

相关内容

  • 没有找到相关文章