3

我正在使用 symfony 1.4 + propel 1.6,我想将我的所有用户数据库导出(索引)到 ElasticSearch。

我已经编写了所有脚本并且一切正常,除了一个问题。我做了一个循环,重复大约 20.000~ 次,每次 memory_usage 增加。

问题是:它不应该,因为我正在销毁所有引用。

我认为 Propel 在某处留下了对我创建的每个对象的静态引用。但是找不到它,因为我已经禁用了实例池。

有人遇到过类似的问题吗?也许有人知道如何调试 PHP 内存限制?(webgrind 没有)我在这段代码调试上花费了最后几个小时,但仍然无法修复它。

// optimizations
    gc_enable();
    Propel::getConnection()->useDebug(false);
    Propel::disableInstancePooling();
// the while
    $offset = 0;
    $perpage = 10;
    $c = SearchUserQuery::create()->limit($perpage);
    do {
        $rs = SearchUserPeer::doSelectStmt($c);
        while ($row = $rs->fetch(PDO::FETCH_NUM))
        {
            $instance = new SearchUser();
            $instance->hydrate($row);
            $data = $instance->toElastic(); // this line makes a lot of memory leak
            $_document = new Elastica\Document($instance->getPrimaryKey(), $data);
            $_type->addDocument($_document);
            unset($_document, $instance);
        }
        $c->offset($offset += $perpage);
    } while( $rs->rowCount() );

函数 $instance->toElastic 是这样的:

public function toElastic()
{
    return Array(
        'profile' => $this->toArray(BasePeer::TYPE_COLNAME, false),
        'info' => $this->getUserInfo()->toArray(BasePeer::TYPE_COLNAME, false),
        'branches' => $this->getElasticBranches(),
    );
}

/**
 * @return array(id,name)
 */
public function getElasticBranches()
{
    $branches = Array();
    foreach ($this->getsfGuardUser()->getUserBranchs() as $branch)
        $branches[] = Array(
            'id' => $branch->getBranchId(),
            'name' => $branch->getName()
        );
    return $branches;
}
4

1 回答 1

5

您在取消设置之前是否尝试过此操作?

// garbage collector problem in PHP 5.3
$instance->clearAllReferences(true);

// remove the variable content before removing the address (with unset)
$instance = null;
$_document = null;
$_type = null;

您可以从此答案中获取更多提示。看看这 3 个链接,真的很有趣,即使其中一个是法语的。

于 2013-01-31T20:38:58.137 回答