Mit dem Fix sind auch Importe von mehreren tausend Artikeln in eigenen Schnittstellen kein Problem mehr.
Beim Import von Produktdaten in ein Shopsystem müssen nicht selten tausende von Datensätzen eingelesen werden. Hierzu bietet Magento DataFlow an, mit dem sich Produkte aus CSV-Dateien oder Excel-XML-Dateien über ein zuvor festgelegtes Schema importieren lassen. Für viele Shops reicht diese Lösung allerdings nicht aus, da häufig direkte Anbindungen an ERP-Systeme oder PIM-Lösungen benötigt werden. Daher kommen insbesondere bei großen Shops indivuelle Schnittstellen zum Einsatz, die entweder direkt innerhalb von Magento oder über die API arbeiten. Aufgrund eines Speicherlecks im Magento Core führt der Import großer Datenmengen auf diesem Weg allerdings schnell dazu, dass der zur Verfügung stehende Arbeitsspeicher vollläuft und der Import abbricht.
Ungeliebte Fehlermeldung: Der verfügbare Arbeitsspeicher ist vollgelaufen
Doch nicht nur beim Import kann dieses Problem auftreten. Mit einem kleinen Test kann man auch beim Laden eines Produktes erkennen, dass der Speicher volläuft:
<?php for($i=1;$i<=100;$i++) { $product = Mage::getModel('catalog/product')->load(0); } ?>
Hier wird 100 Mal ein Product Model geladen. Lässt man sich nun bei jedem Schleiferndurchlauf mit memory_get_usage() den Speicherverbrauch anzeigen, sieht man das Problem sehr deutlich:
Der Speicherverbrauch steigt pro Durchlauf an – im schlimmsten Fall bis zum Abbruch
Die Ursache der Speicherlecks liegt darin begründet, dass der in PHP integrierte Garbage Collector nicht in der Lage ist, sogenannte Circular References in Objekten zu verarbeiten. Das führt dazu, dass diese Speicherbereiche nicht automatisch freigegeben werden, und genau das führt dann zu einem kontinuierlichen Anstieg des verwendeten Arbeitsspeichers. Um dieses Problem zu umgehen, müssen solche Objekte zur Laufzeit manuell freigegeben werden. Ausführliche Informationen zur Circular References in PHP gibt es hier (jeweils englisch):
http://derickrethans.nl/circular_references.php
http://paul-m-jones.com/?p=262
Der Fix
Wir bei Visions haben dieses Problem analysiert und einen kleinen aber wirkungsvollen Fix erarbeitet. Er wird derzeit von den Magento-Entwicklern bei Varien getestet und voraussichtlich bis zum nächsten Release in den Magento Core aufgenommen. Bis dahin können Sie den Fix auch selbst in Ihr System integrieren. Aber Vorsicht: Trotz sorgfältiger Tests können wir keine Garantie für die korrekte Funktion in Ihrer Magento-Installation übernehmen! Bis zur Aufnahme in den Magento Core sollten Sie den Fix keinesfalls auf Produktivsystemen einsetzen.
In der Datei app/code/core/Mage/Eav/Model/Entity/Attribute/Abstract.php wird die neue Funktion __destruct() eingefügt:
public function __destruct() { unset($this->_backend); }
Diese wird in der Datei app/code/Mage/Eav/Model/Entity/Abstract.php in der Funktion walkAttributes() benötigt. Suchen Sie nach dem Code-Block
catch (Exception $e) { $exception = new Mage_Eav_Model_Entity_Attribute_Exception($e->getMessage()); $exception->setAttributeCode($attrCode)->setPart($part); throw $exception; }
und fügen Sie direkt dahinter die folgende Zeile ein:
$attribute->__destruct();
Außerdem wird in der Funktion _collectSaveData() hinter dem Code-Block
elseif (!$attribute->isValueEmpty($v)) { $insert[$attrId] = $v; }
die folgende Zeile eingefügt:
$this->unsetAttributes();
Das war schon alles! Ein erneuter Test zeigt dass der Speicherverbrauch nun konstant ist:
Mit dem Fix bleibt der Speicherverbrauch konstant.
Über den Autor
Sebastian Heuer ist Entwickler bei Visions und arbeitet seit Juni 2008 an Magento Projekten.
Vielen Dank für den Beitrag, hoffentlich wird das auch bald von Varien umgesetzt.
Viele Grüße
Dscho
Heute habe ich mir das Problem im Detail angesehen und bei 3 Shops getestet, ich war überrascht vom Ergebnis. Gut 1/3 weniger Speicherverbrauch. Das Ergebnis habe ich in meinem Blog gezeigt, denn das sollte sich jeder Shopbetreiber genauer ansehen.
Viele Grüße
Johannes Teitge
Leider hat der Fix ein Problem – Aufträge werden fehlerhaft geschrieben und können weder im Backend noch im Frontend angesehen werden :-(
Ein User auf unserem Blog hat den Felder gemeldet.
http://www.mxperts.de/speicherverbrauch-reduzieren/comment-page-1/#comment-749
Viele Grüße
Johannes Teitge
Klasse Artikel, aber hat sich schon etwas zu dem geschilderten Problem von Johannes Teitge ergeben?
Grüße,
Sebastian
Nein, habe bisher leider noch kein Feedback :-(
Grüße
Johannes Teitge
Hallo,
leider können wir aktuell noch kein verwertbares Feedback geben – das Problem wird aktuell bei uns analysiert; sobald ein korrigierter Fix zur Verfügung steht, werden wir ihn hier natürlich veröffentlichen.
Abgesehen davon wird das Speicherleck auch von Varien untersucht, ob und in welcher Form schon eine Lösung in Version 1.4.0 vorliegt, werden wir in den kommenden Tagen anhand der Alpha-Version prüfen und neue Erkenntisse hier veröffentlichen.
Gruß,
Sebastian Heuer
Hallo zusammen,
wie ist denn der Stand bei dem gefundenen Memory Leak? Gibt es im Magento Bugtracker einen entsprechenden Eintrag? Hat jemand Informationen, ob das Problem nun in der Version 1.4.0 behoben sein wird?
Grüße
Sebastian
Was bewirken eigentlich die Einzelne Code Fragmente? Villeicht köne wir das ja gemeinsam durchgehen und versthen weshalb die Stürungen be Produktanlage entstehen.?
Ich hatte vor einiger Zeit versucht ein ähnliches Problem zu lösen und bin zu dem Ergebnis gekommen das ein großes Speicherleck innerhalb der Event Observer zu finden ist.
Mein damaliges Ergebis habe ich hier dokumentiert:
http://www.magentocommerce.com/boards/viewthread/36312/
mit entsprechendem Eintrag im Bugtracker hier: http://www.magentocommerce.com/bug-tracking/issue?issue=5647
10-28-10netmo sagt: Bei mir das selbe Problem wie bei JoernBernd. Ausgeloggt und Cache geleert habe ich nach der Installation..leider ohne Erfolg.Hat nineamd eine Idee? Benutze auch die 1.3.2.4.. +10War diese Antwort hilfreich?
Sebastian Heurer –> Lösung in Version 1.4.0
hat sich da was getan?
hab den fix in magento 1.4 eingebaut. speicher ersparnis von 42 MB auf 24 MB bei export von 1200 Produkten. Fehler: Orders im Adminhtml hatten keine Namen mehr im Grid View. Hab diese Zeile des Fixes wieder auskommentiert:
class: Mage_Eav_Model_Entity_Abstract
function: _collectSaveData
line: $this->unsetAttributes();
Danach sah ich die Namen wieder bei den Bestellungen konnte aber immer noch den Speichergewinn beim Export verzeichnen
Habe eine Idee aufgeschrieben, um den Bug im Fix zu umgehen…
http://blog.tudock.de/startseite/beitrag/2010/11/16/magento-tipp3-ein-fix-fuer-den-fix-speicherlecks-in-magento.html