我正在TYPO3 CMS 6.2 Extbase中编写一个扩展函数,它必须处理大型存储库中的每个对象。如果我有大约10,000个对象,我的函数可以正常工作,但如果我有大约20,000个对象,则会耗尽内存。我该如何处理更大的存储库?
$importRecordsCount = $this->importRecordRepository->countAll();
for ($id = 1; $id <= $importRecordsCount; $id++) {
$importRecord = $this->importRecordRepository->findByUid($id);
/* Do things to other models based on properties of $importRecord */
}
在通过上面的..\GeneralUtility.php:4427
行后,该程序超出TYPO3\CMS\Core\Utility\GeneralUtility::instantiateClass( )
findByUid()
附近的内存。在我的最新测试期间,花了117秒才达到此错误。错误消息是:
致命错误:第4448行的...... \ typo3 \ sysext \ core \ Classes \ Utility \ GeneralUtility.php中允许的内存大小为134217728个字节(试图分配4194304个字节)
如果重要,我不会使用@lazy,因为我稍后会在函数中执行某些处理。
答案 0 :(得分:1)
通常,Extbase不适合处理如此大量的数据。如果需要正确的历史记录等,则可以使用DataHandler
。与使用TYPO3数据库API(DatabaseConnection
,$GLOBALS['TYPO3_DB']
)相比,它也有相当大的开销,这将是性能最佳的方法。请参阅this answer中的评论和教程。
如果您决定使用Extbase API,唯一可行的方法是保留每个X项(尝试在您的设置中起作用)以释放一些内存。从你的代码中我无法真正看到你的操作在哪一点上起作用,但以此为例:
$importRecords = $this->importRecordRepository->findAll();
$i = 0;
foreach ($importRecords as $importRecord) {
/** @var \My\Package\Domain\Model\ImportRecord $importRecord */
// Manipulate record
$importRecord->setFoo('Test');
$this->importRecordRepository->update($importRecord);
if ($i % 100 === 0) {
// Persist after each 100 items
$this->persistenceManager->persistAll();
}
$i++;
}
// Persist the rest
$this->persistenceManager->persistAll();
答案 1 :(得分:1)
根据官方TYPO3网站,建议256M内存限制而不是128M: Source
所以我的第一个建议是首先尝试这样做,它现在可以解决你的问题。你也应该使用importRecordRepository-&gt; findAll();而不是通过迭代uid来获取每条记录,因为有人可能删除了一些记录。
答案 2 :(得分:0)
还有Extbase的clearState函数来释放一些内存:
$this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class)->clearState();