首页 文章

程序耗尽内存读取大型TYPO3 Extbase存储库

提问于
浏览
0

我正在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 */
}

程序在通过上面的 findByUid() 行后,在 TYPO3\CMS\Core\Utility\GeneralUtility::instantiateClass( ) 中超过 ..\GeneralUtility.php:4427 附近的内存 . 在我最近的测试期间,花了117秒才达到此错误 . 错误消息是:

致命错误:在4448行的... \ typo3 \ sysext \ core \ Classes \ Utility \ GeneralUtility.php中,允许的内存大小为134217728个字节(试图分配4194304个字节)

如果重要的话,我不使用@lazy,因为我稍后在函数中做了一些处理 .

2 回答

  • 1

    根据官方TYPO3网站,建议256M内存限制而不是128M:Source

    所以我的第一个建议是首先尝试这样做,它现在可以解决你的问题 . 你也应该使用importRecordRepository-> findAll();而不是通过迭代uid来获取每个记录,因为有人可能已经删除了一些记录 .

  • 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();
    

相关问题