php/symfony/doctrine memory leak?

2022-08-31 00:13:54

我在使用symfony 1.4和教义1.2将对象批量插入数据库时遇到问题。

我的模型有一种名为“Sector”的对象,每个对象都有几个类型为“Cupo”的对象(通常范围从50到200000)。这些物体非常小;只是一个简短的标识符字符串和一个或两个整数。每当用户创建一组扇区时,我都需要自动将所有这些“Cupo”实例添加到数据库中。万一出现任何问题,我正在使用原则事务来回滚所有内容。问题是,在 php 内存不足之前,我只能创建大约 2000 个实例。它目前有128MB的限制,这对于处理使用少于100字节的对象应该绰绰有余。我尝试将内存限制增加到512MB,但php仍然崩溃,这并不能解决问题。我是否正确执行了批量插入,还是有更好的方法?

这是错误:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 71 bytes) in /Users/yo/Sites/grifoo/lib/vendor/symfony/lib/log/sfVarLogger.class.php on line 170

代码如下:

public function save($conn=null){

    $conn=$conn?$conn:Doctrine_Manager::connection();

    $conn->beginTransaction();


    try {
        $evento=$this->object;


        foreach($evento->getSectores() as $s){

            for($j=0;$j<$s->getCapacity();$j++){

                $cupo=new Cupo();
                $cupo->setActivo($s->getActivo());
                $cupo->setEventoId($s->getEventoId());
                $cupo->setNombre($j);
                $cupo->setSector($s);

                $cupo->save();

            }
        }

        $conn->commit();
        return;
    }
    catch (Exception $e) {
        $conn->rollback();
        throw $e;
    }

同样,此代码适用于少于 1000 个的对象,但任何大于 1500 的对象都会失败。感谢您的帮助。


答案 1

尝试做

$cupo->save();
$cupo->free();
$cupo = null;

(但替换我的代码)我仍然有内存溢出。还有其他想法吗?

更新:

我在我的 databases.yml 中创建了一个新环境,如下所示:

all:
  doctrine:
    class: sfDoctrineDatabase
    param:
      dsn: 'mysql:host=localhost;dbname=.......'
      username: .....
      password: .....
      profiler: false

探查器:false entry 禁用 doctrine 的查询日志记录,该日志记录通常会保留您所做的每个查询的副本。它并没有阻止内存泄漏,但我能够通过数据导入获得大约两倍于没有它的时间。

更新 2

我添加了

Doctrine_Manager::connection()->setAttribute(Doctrine_Core::ATTR_AUTO_FREE_QUERY_OBJECTS, true ); 

在运行我的查询之前,并更改了

$cupo = null;

unset($cupo);

现在我的剧本已经愉快地搅动了。我很确定这次它会在没有RAM耗尽的情况下完成。

更新 3

是的。这就是获胜的组合。


答案 2

我刚刚用symfony 1.4做了“守护神化”脚本,并设置了以下内容,阻止了内存占用:

sfConfig::set('sf_debug', false);

推荐