[TYPO3-performance] DataHandler high memory consumption
Stephan Großberndt
s.grossberndt at sidebysite.de
Fri Dec 5 19:29:08 CET 2014
Hi,
I think I found (the or another?) cause for your problem because I had a
similar issue. It is in
TYPO3\CMS\Core\DataHandling\DataHandler::processClearCacheQueue
Due to this dubious construct, which is called for each and every record
added:
foreach (static::$recordsToClearCacheFor as $table => $uids) {
foreach (array_unique($uids) as $uid) {
...
foreach ($pageIdsThatNeedCacheFlush as $pageId) {
if ($pageId >= 0) {
$tagsToClear[] = 'pageId_' . $pageId;
}
}
// Queue delete cache for current table and record
$tagsToClear[] = $table;
$tagsToClear[] = $table . '_' . $uid;
$tagsToClear = array_unique($tagsToClear);
}
}
I am adding 6500 records, so *FOR EACH AND EVERY* record 'pageId_' .
$pageId, $table and $table . '_' . $uid are added to $tagsToClear and
afterwards 'pageId_' . $pageId and $table are removed again for 6499
times. There is no reason to do it like this. array_unique() is meant
here to reduce memory consumption in $tagsToClear but for big arrays
with array_unique() this is terrible - xhprof showed 2,020,470,496 bytes
(~2 gigabyte !!!) of used memory for array_unique() in
processClearCacheQueue()
It is possible to set clearCache_disable=1 to disable clearing of the
cache but there is also a simple code solution to solve this since
entries in this array are meant to be unique anyway:
foreach (static::$recordsToClearCacheFor as $table => $uids) {
foreach (array_unique($uids) as $uid) {
...
foreach ($pageIdsThatNeedCacheFlush as $pageId) {
if ($pageId >= 0) {
$tagsToClear['pageId_' . $pageId] = 'pageId_' . $pageId;
}
}
// Queue delete cache for current table and record
$tagsToClear[$table] = $table;
$tagsToClear[$table . '_' . $uid] = $table . '_' . $uid;
}
}
array_unique memory consumption drops from
IMemUse%: 13064.1%
Incl. MemUse (bytes): 2,020,470,496 bytes (~2 gigabyte !!!)
to
IMemUse%: 4.1%
Incl. MemUse (bytes): 629,464 bytes
There may be optimizations possible like
foreach (static::$recordsToClearCacheFor as $table => $uids) {
foreach (array_unique($uids) as $uid) {
...
foreach ($pageIdsThatNeedCacheFlush as $pageId) {
$pageKey = 'pageId_' . $pageId;
if ($pageId >= 0 && !isset($tagsToClear[$pageKey])) {
$tagsToClear[$pageKey] = $pageKey;
}
}
// Queue delete cache for current table and record
if (!isset($tagsToClear[$table])) {
$tagsToClear[$table] = $table;
}
$tagsToClear[$table . '_' . $uid] = $table . '_' . $uid;
}
}
but even without those its SOOOO much better...
I've created an issue: https://forge.typo3.org/issues/63615
Regards,
Stephan
More information about the TYPO3-performance
mailing list