Bug #92975
closedObject references are not cleared completely by using clearState - hinting at potential memory leak
0%
Description
As detailed in here: #89845 there is a problem with trailing object references in Extbase.
If one loads an object through a repository, then persists said object, unsets its reference and clearState() the persistenceManager, the object should no longer have a reference to it. PHP will instantly free its memory. That mechanic has been working in TYPO3 Extbase from 6 through 8/9. Since version 10 it seems that calling clearState() on the persistenceManager - even though it's clearing all obvious reference it has created itself - no longer removes all references from within Extbase to that object.
The result: PHP will never free the memory of any object loaded in Extbase, even if they are no longer in use. Somewhere in the bowels of the persistenceManager/Session construct we have something pointing to those objects.
Drop In Test Case (PHP 7.4) to proof there is a problem (copy it in any action of any controller of any plugin):
// TYPO3 trailing reference example - make sure you are not logged in in the backend
$persistenceManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
$backendUserRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Beuser\Domain\Repository\BackendUserRepository::class);
$firstUser = $backendUserRepository->findByUid(1);
$weakUserRef = \WeakReference::create($firstUser);
unset($firstUser);
$persistenceManager->clearState();
// After this point $firstUser should have nothing pointing to it
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($weakUserRef->get(), 'I AM STILL ALIVE! But... I should be dead');
// Regular PHP example of how references work
$plainBackendUserObject = new \TYPO3\CMS\Beuser\Domain\Model\BackendUser();
$weakPlainUserRef = \WeakReference::create($plainBackendUserObject);
unset($plainBackendUserObject);
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($weakPlainUserRef->get(), 'I am NULL and nothing. I am the void. The emptiness I should be');
In many practical Extbase cases those trailing/remaining references won't be a problem, since the memory useage of a single page request will rarely be problematic. But for longer running actions or Command Tasks, that process more data with Extbase those references grow to be a serious problem. Additionally the core framework of TYPO3 should not suddenly start creating memory leaks in version 10.
In the old bug report it was stated that clearState() is an @interal function, I'd like to add: It hasn't been for years AND it's the only tool us Extbase/extension coders have to control the memory hunger of Extbase.