dump("Before Memory: " . LogUtility::getMemoryUsage());
$this->_em->getConnection()->getConfiguration()->setSQLLogger(null);
$start = $i*self::COUNT;
$entityName = $this->getEntityName();
$query = $this->_em->createQueryBuilder()->select("c")->from($entityName, "c");
$query->setFirstResult($start);
$query->setMaxResults(self::COUNT);
$query = $query->getQuery();
$query->useQueryCache(false);
$query->useResultCache(false);
$result = $query->getResult(Query::HYDRATE_OBJECT);
//$query->expireQueryCache(true);
//unset($result);
for($i=0;$i<count($result);$i++):
$this->_em->detach($result[$i]);
endfor;
$this->_em->clear();
@$query = null;
@$result = null;
unset($query,$result);
dump("After Memory: " . LogUtility::getMemoryUsage());
嘿,我对这段代码变得疯狂,我试图在大约 5000 个实体的教义调用之后释放内存,但它不会释放内存,我真的不明白为什么。
"Before Memory: 19.5 mb"
"After Memory: 80 mb"
我尝试了分离,清除,取消设置,销毁功能,免费功能,使用sqllogger,缓存,我现在变得完全疯狂了!
另外,如果我使用HYDRATE_ARRAY,我可以轻松地取消设置 var 并释放内存,但是当它是关于对象的时,这就会成为一个问题。我的相关实体都有分离级联操作,是的,如果你问我报告内存的方式是否好,这里是函数
static public function getMemoryUsage() {
$size = memory_get_usage(true);
$unit=array('b','kb','mb','gb','tb','pb');
$size = @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
return $size;
}
感谢您的帮助,这让我发疯了!哦,而且,这是从命令行运行的,调用获取存储库的控制器,控制器就是这么简单
__construct(EntityManager $em, Logger $logger);
public function executeAction (){
$this->repo->updateData(0);
}
编辑:也尝试使用gc_collect_cycles((,没有区别
编辑2:我需要这个对象,因为我即将更新它。否则会拿走数组,问题就解决了
EDIT3:还清除了日志文件夹,我的选择用完了,我无法承受不释放内存,因为脚本将更新 50k 个实体。
========================== SOLUTION ==================================
$iterableResult= $query->iterate();
foreach ($iterableResult as $row) {
$this->_em->detach($row[0]);
}
"Memory: 19.5 mb"
"Memory: 34.5 mb"
解决方案在于迭代函数,该函数必须具有某种使其工作的机制!所以基本上,不要认为它只是一个分离,你必须使用迭代类的学说才能使这个 bash 处理工作!!现在有10Mb的开销,但我不会把我的头发扯下来了解它去了哪里。无论如何,伙计们,你们去吧!当教义给你一种方法时,复制它!无论如何,如果有人能向我们解释为什么迭代函数具有这种特殊的魔力,那么对于经历过与我同样挣扎的其他人来说,这将是一件好事。
http://doctrine-orm.readthedocs.org/en/latest/reference/batch-processing.html
已知 Doctrine2 在长时间操作期间会出现一些内存泄漏。例如,请参阅此博客文章
就我而言,禁用记录器为我节省了一些内存,但不是全部。
$this->em->getConnection()->getConfiguration()->setSQLLogger(null);