2008-10-23 9 views
6

Wir haben eine große Management-Software, die große Berichte aller Art produziert, basierend auf zahlreichen Schleifen, mit Datenbank-Retrieval, Objekte Kreationen (viele), und so weiter.Strategien zum Umgang mit Speicherverbrauch in PHP5?

Auf PHP4 konnte es glücklich mit einem Speicherlimit von 64 MB laufen - jetzt haben wir es auf einen neuen Server verschoben und mit der gleichen Datenbank - gleichen Code, die gleichen Berichte werden nicht ohne ein Gig von Speicherlimit kommen ...

Ich weiß, dass PHP5 hat unter der Haube ziemlich viele Dinge geändert, aber gibt es eine Möglichkeit, es zu verhalten?

Die Frage am Ende ist, welche Strategien wenden Sie an, wenn Sie Ihre Skripte auf einer Diät haben müssen?

Antwort

6

Ein großes Problem, auf das wir gestoßen sind, waren zirkuläre Referenzen zwischen Objekten, die sie daran hindern, Speicher freizugeben, wenn sie nicht mehr in Geltung sind.

Je nach Ihrer Architektur können Sie __destruct() verwenden und Referenzen manuell entfernen. Für unser Problem habe ich die Klassen restrukturiert und die Zirkelbezüge entfernt.

0

Seit der Umstellung auf den neuen Server haben Sie verifiziert, dass Ihre MySQL- und PHP-Systemvariablen identisch mit denen auf Ihrem alten Server sind?

PHP5 hat eine Menge neuer Funktionen eingeführt, aber aufgrund der Abwärtskompatibilität, glaube ich nicht, dass die Unterschiede zwischen PHP5 und PHP4 einen großen Einfluss auf die Performance einer Anwendung haben, deren Code und Datenbank nicht funktionieren wurde verändert.

Verwenden Sie auch die gleiche Version von Apache oder IIS?

Es klingt wie ein Problem, das eher zu Ihrem neuen Systemumgebung verwandt ist als mit einem Upgrade von PHP4 bis 5.

0

Bertrand,

Wenn Sie in Refactoring den vorhandenen Code interessiert sind, dann würde ich empfehlen, dass Sie beim Ausführen von Berichten zuerst Ihre CPU- und Speicherauslastung überwachen. Sperren Sie Ihren SQL-Server oder sperren Sie Apache (was passiert, wenn der PHP-Code viel Stress in das System bringt)?

Ich arbeitete an einem Projekt, das anfangs so stark an MySQL hängen blieb, dass wir den gesamten Berichterstellungsprozess neu gestalten mussten. Als wir fertig waren, wurde der Ladevorgang jedoch einfach über den komplexeren PHP-Code an Apache übertragen. Unsere endgültige Lösung bestand darin, den Datenbankentwurf neu zu strukturieren, um eine bessere Leistung für Berichtsfunktionen zu bieten, und PHP dazu zu nutzen, die Lücke zu schließen, die wir in MySQL nativ nicht erreichen konnten.

Je nach Art der Berichte können Sie die Denormalisierung der Daten, die für die Berichte verwendet werden, in Betracht ziehen. Sie könnten sogar in Erwägung ziehen, eine zweite Datenbank zu erstellen, die als Data Warehouse dient und nicht nach OLTP-Prinzipien, sondern nach OLAP-Prinzipien konzipiert ist. Sie können bei Wikipedia für eine allgemeine Erklärung von OLAP und Data Warehousing beginnen.

Bevor Sie jedoch ernsthaftes Refactoring in Betracht ziehen, haben Sie mit phpinfo() verifiziert, dass Ihre Umgebungen ausreichend ähnlich sind. für PHP und SHOW VARIABLES; in MySQL?

0

Ein Gig!?!

sogar 64MB ist groß.

Wenn man die Diskrepanz zwischen Umgebungen ignoriert (was sehr merkwürdig klingt), klingt es so, als ob der Code ein Re-Factoring benötigt.

Jede Möglichkeit, dass Sie Ihren Code neu berechnen können, damit die Ergebnismengen aus Datenbankabfragen nicht in Arrays ausgegeben werden. Ich würde empfehlen, dass Sie einen Iterator für Ihre Ergebnismengen erstellen. (Daher können Sie sie für die meisten Zwecke als Array behandeln.) Es gibt einen großen Unterschied zwischen der Behandlung eines Datensatzes und der Verarbeitung von jeweils 10.000 Datensätzen.

Zweitens, schauen Sie sich an, ob Ihr Code mehrere Instanzen der Daten erstellt. Können Sie die Objekte als Referenz übergeben? (Verwenden Sie die '&'). Ähnliches mussten wir bei einer frühen Variante des Horde-Frameworks tun. Ein 1-MB-Anhang würde bei zahlreichen Aufrufen, die den gesamten Datensatz als Kopie und nicht als Referenz übermittelten, auf 50 MB hinauswachsen.

+1

Objekte in PHP5 werden automatisch als Referenz übergeben. – grantwparks

+0

wirklich ?! würde das nicht die Idee des Geltungsbereichs vereiteln. Wenn Sie ein Objekt an eine Funktion übergeben, arbeitet diese Funktion auf einer Kopie des Objekts, nicht auf dem tatsächlichen Objekt. (es sei denn, Sie übergeben das Objekt als Referenz.) – Bingy

+0

Was @grantwparks gesagt hat, ist eine grobe Vereinfachung ... http://php.net/manual/en/language.oop5.references.php 'Einer der Schlüssel -Punkte von PHP 5 OOP, das oft erwähnt wird, ist, dass "Objekte standardmäßig von Referenzen übergeben werden". Dies ist nicht vollständig richtig. Dieser Abschnitt korrigiert diesen allgemeinen Gedanken anhand einiger Beispiele. – MrMesees

Verwandte Themen