Import Test
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.

memory_error
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:

Product Load Memory Leak
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:

Product Load Fixed
Mit dem Fix bleibt der Speicherverbrauch konstant.

Über den Autor
Sebastian Heuer ist Entwickler bei Visions und arbeitet seit Juni 2008 an Magento Projekten.

18 thoughts

  1. 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

  2. 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

  3. 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

  4. Was bewirken eigentlich die Einzelne Code Fragmente? Villeicht köne wir das ja gemeinsam durchgehen und versthen weshalb die Stürungen be Produktanlage entstehen.?

    1. 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?

  5. 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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s