Mon*_*roM 45 orm memory-leaks symfony doctrine-orm
实际上我对symfony2和doctrine2的组合有很多麻烦.我必须处理大量数据集(大约2-3百万次写入和读取),并且必须做很多额外的工作以避免内存不足.
我找出了2个要点,即"泄漏"内存(它们实际上并没有泄漏,而是分配了很多)
Entitymanager实体存储(我不知道这个的真实名称)似乎它保留了所有处理过的entites,你必须定期清除这个存储
$entityManager->clear()
Doctrine QueryCache - 它缓存所有使用的查询,我发现的唯一配置是你能够决定你想要使用什么类型的Cache.我没有发现全局禁用每个查询禁用它的有用标志.因此通常使用该函数为每个查询对象禁用它
$qb = $repository->createQueryBuilder($a); $query = $qb->getQuery(); $query->useQueryCache(false); $query->execute();
所以..这就是我现在想出来的..我的问题是:
是否有一种简单的方法可以从Entitymanagerstorage中拒绝某些对象?有没有办法在entitymanager中设置querycache?我可以在symonfony doctrine配置中配置这种缓存行为吗?
如果有人对我有一些不错的提示,那将是非常酷的..否则这可能会帮助一些菜鸟......
CYA
Ser*_*rgi 86
有点晚了,但我想我刚刚在 Benjamin Eberlei的Google网上找到了一个回复你问题的帖子:正如Doctrine Configuration Reference所述,默认情况下SQL连接的记录设置为kernel.debug的值,所以如果已将debug调试为true的实例化AppKernel,则SQL命令将在每次迭代时存储在内存中.
您应该将AppKernel实例化为false,在配置YML 中将日志记录设置为false,或者在使用EntityManager之前将SQLLogger手动设置为null
$em->getConnection()->getConfiguration()->setSQLLogger(null);
Run Code Online (Sandbox Code Playgroud)
luc*_*nov 13
1.关闭日志记录和分析app/config/config.yml
doctrine:
dbal:
driver: ...
...
logging: false
profiling: false
Run Code Online (Sandbox Code Playgroud)
或者在代码中
$this->em->getConnection()->getConfiguration()->setSQLLogger(null);
Run Code Online (Sandbox Code Playgroud)
2.强制垃圾收集器.如果您主动使用CPU,那么垃圾收集器会等待,您很快就会发现自己没有内存.
首先启用手动垃圾收集管理.gc_enable()在代码中的任何位置运行.然后运行gc_collect_cycles()强制垃圾收集器.
例
public function execute(InputInterface $input, OutputInterface $output)
{
gc_enable();
// I'm initing $this->em in __construct using DependencyInjection
$customers = $this->em->getRepository('AppBundle:Customer')->findAll();
$counter = 0;
foreach ($customers as $customer) {
// process customer - some logic here, $this->em->persist and so on
if (++$counter % 100 == 0) {
$this->em->flush(); // save unsaved changes
$this->em->clear(); // clear doctrine managed entities
gc_collect_cycles(); // PHP garbage collect
// Note that $this->em->clear() detaches all managed entities,
// may be you need some; reinit them here
}
}
// don't forget to flush in the end
$this->em->flush();
$this->em->clear();
gc_collect_cycles();
}
Run Code Online (Sandbox Code Playgroud)
如果你的桌子非常大,请不要使用findAll.使用迭代器 - http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/batch-processing.html#iterating-results
$em->getConnection()->getConfiguration()->setSQLLogger(null);
gc_collect_cycles()后$em->clear()$em->clear();
gc_collect_cycles();
不要忘记将zend.enable_gc设置为1,或者在使用gc_collect_cycles()之前手动调用gc_enable ()
--no-debug如果从控制台运行命令,请添加选项.| 归档时间: |
|
| 查看次数: |
24436 次 |
| 最近记录: |