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.
Updated by Benjamin Franzke almost 4 years ago
Extbase DataMapper has an event named AfterObjectThawedEvent
.
This event references the object that is being generated.
Now, when EXT:adminpanel is installed, all events are being tracked (thus referenced).
That means the reference to the object is never released, despite the call to clearState().
Can you confirm that this bug doesn't happen when EXT:adminpanel is disabled?
Edit: your example codes reports that the object has been destroyed, when I disable adminpanel.
So my question is basically: Does that also help in your production scenario, or do we have yet another problem there?
Updated by Simon Gilli almost 4 years ago
- Related to Bug #89845: TYPO3 Extbase: clearState not clearing much added
Updated by Johannes Rebhan almost 4 years ago
The suggestion to disable ext:adminpanel solves the trailing references issue. Thanks so much.
Updated by Oliver Bartsch almost 4 years ago
- Status changed from New to Closed
Hi, I'll close this issue since it seems to be solved. If you feel there is still something not working, please let me know and I'll create a new issue or reopen this one.