Memory TYPO3 Extbase:clearState不释放内存

Memory TYPO3 Extbase:clearState不释放内存,memory,typo3,extbase,typo3-9.x,Memory,Typo3,Extbase,Typo3 9.x,我有一个用Extbase编写的调度器导入作业,内存使用率非常高。 在Typo37.6中,我可以用 $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class)->clearState(); 但升级到TYPO3 9.5之后,“clearState”似乎不再像以前那样工作了,这个函数只释放了少量内存 我已经编写了一个简单的示例代码来演示这个问题。此示例可以在E

我有一个用Extbase编写的调度器导入作业,内存使用率非常高。 在Typo37.6中,我可以用

$this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class)->clearState();
但升级到TYPO3 9.5之后,“clearState”似乎不再像以前那样工作了,这个函数只释放了少量内存

我已经编写了一个简单的示例代码来演示这个问题。此示例可以在Extbase控制器中运行,无需在调度程序上下文中运行

var_dump(memory_get_usage());
$v1 = $this->frontendUserRepository->findAll();
foreach($v1 as $vv1) {
    $a1 = $this->frontendUserRepository->findOneByUid($vv1->getUid());
}
var_dump(memory_get_usage());
$this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class)->clearState();
var_dump(memory_get_usage());

输出是
int(49013528)int(565877768)int(543894472)
:通过“findOneByUid”从数据库检索用户会消耗大量内存,因为对象存储在某个PHP变量中,我喜欢释放这些内存。在TYPO3 7中,这与函数“clearState”一起工作。

这是您正在使用的方法:


    /**
     * Clears the in-memory state of the persistence.
     *
     * Managed instances become detached, any fetches will
     * return data directly from the persistence "backend".
     *
     * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
     */
    public function clearState()
    {
        $this->newObjects = [];
        $this->addedObjects = new ObjectStorage();
        $this->removedObjects = new ObjectStorage();
        $this->changedObjects = new ObjectStorage();
        $this->persistenceSession->destroy();
    }
所以在我看来,调用它一点用处都没有,因为它只是清除任何将使用
persistAll()
处理的堆栈。如果要清除这样的堆栈,为什么要先写入它?
也许我缺少函数的意义,但至少它通常不会删除太多数据。
我可能会在扩展中使用该函数,如果结果表明某些条件会重置任何准备好的数据库操作,但这对于调度程序任务来说并不重要,应该依赖于特殊条件,而不是系统地完全删除堆栈

问题是要删除哪种缓存。

这里仍然提到了,也许这就是你想要实现的。

这是你正在使用的方法:


    /**
     * Clears the in-memory state of the persistence.
     *
     * Managed instances become detached, any fetches will
     * return data directly from the persistence "backend".
     *
     * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\NotImplementedException
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
     */
    public function clearState()
    {
        $this->newObjects = [];
        $this->addedObjects = new ObjectStorage();
        $this->removedObjects = new ObjectStorage();
        $this->changedObjects = new ObjectStorage();
        $this->persistenceSession->destroy();
    }
所以在我看来,调用它一点用处都没有,因为它只是清除任何将使用
persistAll()
处理的堆栈。如果要清除这样的堆栈,为什么要先写入它?
也许我缺少函数的意义,但至少它通常不会删除太多数据。
我可能会在扩展中使用该函数,如果结果表明某些条件会重置任何准备好的数据库操作,但这对于调度程序任务来说并不重要,应该依赖于特殊条件,而不是系统地完全删除堆栈

问题是要删除哪种缓存。

这里仍然提到了,也许这就是您想要实现的。

嗨,David,在调用persistAll()之后,我执行了一个clearState()来释放内存。调度程序作业运行超过一个小时并处理许多对象,这有助于不消耗太多内存。现在,在TYPO3 9中,此导入作业消耗13GB内存甚至更多。销毁persistenceSession肯定会释放大部分内存,因为我从数据库中检索到的所有数据都存储在那里,但这似乎在TYPO3 9中有一个问题。@Sven对它是必需的感到惊讶,因为我假设在持久化之后,内存会自动清理相关对象。但老实说,我现在不知道,只好抬头看看。在我看来,一个消耗如此多内存的导入作业是没有用的,应该重写为按顺序工作,包括在每个顺序之后清理内存(如果需要)。调度程序的任务将是多余的。嗨,David,我通过repository类从数据库中检索了许多记录,TYPO3将它们存储在某个持久化层($this->persistenceSession),持久化(即在数据库中更新/插入更改/新对象)不会从中删除对象。我将在我的问题中添加更多的代码。嗨,David,在调用persistAll()之后,我执行一个clearState()来释放内存。调度程序作业运行超过一个小时并处理许多对象,这有助于不消耗太多内存。现在,在TYPO3 9中,此导入作业消耗13GB内存甚至更多。销毁persistenceSession肯定会释放大部分内存,因为我从数据库中检索到的所有数据都存储在那里,但这似乎在TYPO3 9中有一个问题。@Sven对它是必需的感到惊讶,因为我假设在持久化之后,内存会自动清理相关对象。但老实说,我现在不知道,只好抬头看看。在我看来,一个消耗如此多内存的导入作业是没有用的,应该重写为按顺序工作,包括在每个顺序之后清理内存(如果需要)。调度程序的任务将是多余的。嗨,David,我通过repository类从数据库中检索了许多记录,TYPO3将它们存储在某个持久化层($this->persistenceSession),持久化(即在数据库中更新/插入更改/新对象)不会从中删除对象。我将在我的问题中添加一些代码。根据您对问题的更改和新的代码示例:
$v1
将所有
fe_用户
作为对象保存,并且在您第二次
var_dump
时,
$a1
保存
fe_用户的最后记录
。我看不出数据是在持久性级别加载的,所以我认为内存使用量是565877768是合理的。也可以在循环之前调试内存使用情况。如果您只想通过
findOneByUid($uid)
获取数据,那么您应该创建
$a
一个数组或
objectStorage
-对象,并将所有记录加载到其中,然后您可以销毁
$v1
。尽管如此,我从不认为此后的内存使用会比现在少。此外,我不认为有理由首先使用
findAll()
加载数据,然后仍然使用
findByUid()
。如果您想保留一般结构(不管其意义如何),那么就编写一个存储库函数,首先只获取
$v1
中的
uid
而不是所有数据。这个数据量要小得多,因此对内存使用没有多大影响。@David:这只是一个示例代码,用于演示“clearState”的问题。这不是我想要优化的代码。我只是想在脚本执行期间释放一些内存