我在PHP 7.0.22上使用了Docfine Paginator的Symfony命令。該命令必須處理來自大型表格的數據,因此我以100個項目爲單位進行處理。問題是,在幾百個循環後,它會填充256M內存。作爲對OOM措施(外的內存)我使用:Doctrine Paginator填滿內存
$em->getConnection()->getConfiguration()->setSQLLogger(null);
- 禁用SQL記錄器,填充內存用於運行許多SQL腳本記錄的查詢命令$em->clear();
- 分離從學說中的所有對象在每次循環
我已經把一些垃圾場與memory_get_usage()
檢查發生了什麼事情,似乎是在命令在每次調用$paginator->getIterator()->getArrayCopy();
增加了回收不乾淨儘可能多的結尾。
我甚至試圖手動收集垃圾每個循環與gc_collect_cycles()
,但仍然沒有區別,命令開始使用18M和增加約每隔幾百個項目〜2M。還試圖手動取消設置結果和查詢生成器...什麼也沒有。我刪除了所有的數據處理,只保留了select查詢和paginator,並得到了相同的行爲。
任何人有任何想法我應該看看下一個?
注意:對於這類操作,256M應該足夠了,所以請不要推薦提示增加允許內存的解決方案。
條紋下來方法看起來是這樣的:由學說分頁程序產生
protected function execute(InputInterface $input, OutputInterface $output)
{
// Remove SQL logger to avoid out of memory errors
$em = $this->getEntityManager(); // method defined in base class
$em->getConnection()->getConfiguration()->setSQLLogger(null);
$firstResult = 0;
// Get latest ID
$maxId = $this->getMaxIdInTable('AppBundle:MyEntity'); // method defined in base class
$this->getLogger()->info('Working for max media id: ' . $maxId);
do {
// Get data
$dbItemsQuery = $em->createQueryBuilder()
->select('m')
->from('AppBundle:MyEntity', 'm')
->where('m.id <= :maxId')
->setParameter('maxId', $maxId)
->setFirstResult($firstResult)
->setMaxResults(self::PAGE_SIZE)
;
$paginator = new Paginator($dbItemsQuery);
$dbItems = $paginator->getIterator()->getArrayCopy();
$totalCount = count($paginator);
$currentPageCount = count($dbItems);
// Clear Doctrine objects from memory
$em->clear();
// Update first result
$firstResult += $currentPageCount;
$output->writeln($firstResult);
}
while ($currentPageCount == self::PAGE_SIZE);
// Finish message
$output->writeln("\n\n<info>Done running <comment>" . $this->getName() . "</comment></info>\n");
}