Gui*_*Don 5 php memory symfony doctrine-orm
我正在尝试使用Doctrine2和Symfony2 fixture bundle在MySQL数据库中插入大量数据(30 000多行).
我看着正确的方法去做.我看到很多关于内存泄漏和Doctrine的问题,但对我来说没有令人满意的答案.通常是Doctrine clear()函数.
所以,我做了各种各样的形状:
while (($data = getData()) {
$iteration++;
$obj = new EntityObject();
$obj->setName('henry');
// Fill object...
$manager->persist($obj);
if ($iteration % 500 == 0) {
$manager->flush();
$manager->clear();
// Also tried some sort of:
// $manager->clear($obj);
// $manager->detach($obj);
// gc_collect_cycles();
}
}
Run Code Online (Sandbox Code Playgroud)
flush()(在我确定的情况下),PHP内存仍然很疯狂.事实上,每次刷新实体时,内存会根据批量大小和实体而上升一定量,直到达到致命的允许内存大小耗尽错误.使用非常小的实体,它可以工作,但内存消耗增加太多:几MB而应该是KB.
clear(),detach()或调用GC似乎没有产生效果的.它只清除一些KB.
我的做法有缺陷吗?我在某处错过了什么吗?这是一个错误吗?
更多信息:
flush()记忆几乎没动;编辑(部分解决方案):
@qooplmao带来了一个显着降低内存消耗的解决方案,禁用doctrine sql logger: $manager->getConnection()->getConfiguration()->setSQLLogger(null);
然而,它仍然异常高并且在增加.
Gui*_*Don 10
我使用这个资源解决了我的问题,正如@Axalix建议的那样.
这是我修改代码的方式:
// IMPORTANT - Disable the Doctrine SQL Logger
$manager->getConnection()->getConfiguration()->setSQLLogger(null);
// SUGGESION - make getData as a generator (using yield) to to save more memory.
while ($data = getData()) {
$iteration++;
$obj = new EntityObject();
$obj->setName('henry');
// Fill object...
$manager->persist($obj);
// IMPORTANT - Temporary store entities (of course, must be defined first outside of the loop)
$tempObjets[] = $obj;
if ($iteration % 500 == 0) {
$manager->flush();
// IMPORTANT - clean entities
foreach($tempObjets as $tempObject) {
$manager->detach($tempObject);
}
$tempObjets = null;
gc_enable();
gc_collect_cycles();
}
}
// Do not forget the last flush
$manager->flush();
Run Code Online (Sandbox Code Playgroud)
最后但并非最不重要的是,当我将此脚本与Symfony数据夹具一起使用时,在命令中添加--no-debug参数也非常重要.然后内存消耗稳定.