16 Stimmen

Probleme mit PHP beim Versuch, ein großes Array zu erstellen

Hier ist mein Code, der ein 2D-Array mit Nullen erstellt. Die Array-Dimensionen sind (795,6942):

function zeros($rowCount, $colCount){
    $matrix = array();
    for ($rowIndx=0; $rowIndx<$rowCount; $rowIndx++){
        $matrix[] = array();
        for($colIndx=0; $colIndx<$colCount; $colIndx++){
            $matrix[$rowIndx][$colIndx]=0;
        }
    }
    return $matrix;
}

$matrix = zeros(795,6942);

Und hier ist der Fehler, den ich erhalte:

Zugewiesene Speichergrenze von 134217728 Bytes erschöpft (Versuch, 35 Bytes zuzuweisen)

Irgendwelche Ideen, wie man das lösen kann?

32voto

Pascal MARTIN Punkte 384469

Als schnelle Berechnung versuchen Sie also, ein Array zu erstellen, das enthält :

795*6942 = 5,518,890

Ganze Zahlen.

Wenn wir davon ausgehen, dass eine ganze Zahl auf 4 Byte gespeichert ist (d.h. 32 Bits; in PHP verwendet, sollte es nicht weniger sein), bedeutet das :

5518890*4 = 22,075,560

Bytes.

OK, schnelle Berechnung... das Ergebnis ist "es sollte OK sein".

Aber die Dinge sind leider nicht so einfach :-(
Ich nehme an, es hängt damit zusammen, dass Daten von PHP mit einer internen Datenstruktur gespeichert werden, die viel komplizierter ist als eine einfache 32-Bit-Ganzzahl

Nun, nur aus Neugier, lassen Sie uns Ihre Funktion ändern, damit sie am Ende jeder äußeren for-Schleife ausgibt, wie viel Speicher verwendet wird:

function zeros($rowCount, $colCount){
    $matrix = array();
    for ($rowIndx=0; $rowIndx<$rowCount; $rowIndx++){
        $matrix[] = array();
        for($colIndx=0; $colIndx<$colCount; $colIndx++){
            $matrix[$rowIndx][$colIndx]=0;
        }
        var_dump(memory_get_usage());
    }
    return $matrix;
}

Damit erhalte ich eine Ausgabe von diesem Typ _(PHP 5.3.2-dev auf einem 64-Bit-System; memory_limit ist auf 128MB eingestellt -- was bereits viel ist !)_ :

int 1631968
int 2641888
int 3651808
...
...
int 132924168
int 133934088
Fatal error: Allowed memory size of 134217728 bytes exhausted

Dies bedeutet, dass jede Iteration der äußeren for-Schleife etwa 1,5 MB Speicher benötigt -- und ich komme nur auf 131 Iterationen, bevor das Skript den Speicher erschöpft hat ; und nicht auf 765 wie Sie wollten.

Angenommen, Sie haben Ihr memory_limit auf 128M eingestellt, müssten Sie es auf etwas viel höheres einstellen -- wie

128*(765/131) = 747 MB

Nun, selbst mit

ini_set('memory_limit', '750M');

reicht es immer noch nicht... mit 800MB scheint es ausreichend zu sein ;-)

Aber ich würde definitiv nicht empfehlen, memory_limit auf einen so hohen Wert einzustellen!

(Wenn Sie 2GB RAM haben, wird Ihr Server nicht mehr als 2 gleichzeitige Benutzer verarbeiten können ^^ ;; Ich würde das ehrlich gesagt nicht testen, wenn mein Computer 2GB RAM hätte)

Die einzige Lösung, die ich hier sehe, ist, dass Sie Ihr Design überdenken müssen: Es muss etwas anderes geben, was Sie tun können, als diesen Teil des Codes zu verwenden :-)

(Übrigens: Vielleicht bedeutet "Ihr Design überdenken" die Verwendung einer anderen Sprache als PHP : PHP ist großartig für die Entwicklung von Websites, aber nicht für jedes Problem geeignet)

5voto

Kyle Punkte 321

Die Standard-PHP-Array-Implementierung ist sehr speicherintensiv. Wenn Sie nur Ganzzahlen speichern (und viele davon), sollten Sie sich wahrscheinlich SplFixedArray ansehen. Es verwendet einen regulären zusammenhängenden Speicherblock, um die Daten zu speichern, im Gegensatz zur traditionellen Haschstruktur.

1voto

CJD Punkte 762

Sie sollten versuchen, die Menge des verfügbaren Speichers für PHP zu erhöhen:

ini_set('memory_limit', '32M');

in Ihrer PHP-Datei.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X