php-memprof ist eine schnelle und genaue Speicherprofilierungserweiterung für PHP, mit der die Ursache von Speicherlecks ermittelt werden kann.
Die Erweiterung verfolgt die Zuweisung und Freigabe von Speicherblöcken, um die Menge an Speicher zu melden, die durch jede Funktion, Methode oder Datei in einem Programm verloren geht.
Meldet nicht freigegebenen Speicher an beliebigen Stellen im Programm
Gibt das Profil im Callgrind-, Pprof- oder Raw-Array-Format aus
Kann den von PHP selbst und nativem Malloc zugewiesenen Speicher verfolgen
php-memprof hängt von libjudy und sys/queue.h ab.
Auf Debian-basierten Distributionen können die Abhängigkeiten installiert werden mit:
# Debian or Ubuntu: apt install libjudy-dev
Auf Alpine:
# Alpine apk add judy-dev bsd-compat-headers
Auf MacOS:
# install libjudy dependency: brew install traildb/judy/judy
Stellen Sie sicher, dass Sie Abhängigkeiten installieren, und gehen Sie dann wie folgt vor:
pecl install memprof
Unter MacOS: JUDY_DIR=$(brew --prefix traildb/judy/judy) pecl install memprof
Hinweis Wenn libjudy in einem nicht standardmäßigen Pfad installiert wird (nicht /usr oder /usr/local), verwenden Sie bitte die unten stehende manuelle Installationsmethode.
Stellen Sie sicher, dass Sie Abhängigkeiten installieren, und gehen Sie dann wie folgt vor:
Laden Sie die Quelle herunter und führen Sie die folgenden Befehle im Quellverzeichnis aus:
phpize ./configure make make install
Hinweis Wenn libjudy in einem nicht standardmäßigen Pfad installiert ist (nicht /usr oder /usr/local), können Sie es wie folgt angeben:
./configure --with-judy-dir=/opt/homebrew/Cellar/judy/1.0.5
Benutzer von Arch Linux bevorzugen möglicherweise die Installation des inoffiziellen Pakets php-memprof mit makepkg
oder ihrem bevorzugten AUR-Helfer. Bei Verwendung yay
zum Beispiel:
yay -S php-memprof
Bitte melden Sie alle Probleme mit diesem Paket auf der AUR-Seite.
Die Erweiterung kann über die Befehlszeile geladen werden, nur für ein Skript:
php -dextension=memprof.so script.php
Oder dauerhaft, in php.ini:
extension=memprof.so
Die Erweiterung verursacht keinen Overhead, wenn keine Profilerstellung erfolgt, sodass sie standardmäßig in Entwicklungsumgebungen geladen werden kann.
Der einfachste Weg, memprof
zu verwenden, besteht darin, das Speicherprofil speichern zu lassen, wenn das Speicherlimit des Programms überschritten wird.
dump_on_limit
-Modus Die Profilerstellung im dump_on_limit
-Modus wird beim Start der Anforderung aktiviert, wenn einer dieser Punkte zutrifft:
Die Umgebungsvariable MEMPROF_PROFILE
ist gleich dump_on_limit
$_GET["MEMPROF_PROFILE"]
ist gleich dump_on_limit
$_POST["MEMPROF_PROFILE"]
ist gleich dump_on_limit
Für Befehlszeilenskripte können wir die Umgebungsvariable festlegen:
MEMPROF_PROFILE=dump_on_limit php test.php
Für Webskripte können wir die Variable $_GET
festlegen:
curl http://127.0.0.1/test.php?MEMPROF_PROFILE=dump_on_limit
Oder die Variable $_POST
:
curl -d MEMPROF_PROFILE=dump_on_limit http://127.0.0.1/test.php
Hinweis Die Funktion
memprof_enabled_flags()
kann aufgerufen werden, um zu überprüfen, ob die Profilerstellung derzeit imdump_on_limit
-Modus aktiviert ist.
In diesem Modus speichert memprof
das Profil automatisch, wenn das Programm das Speicherlimit überschreitet (wenn PHP einen Fehler wie Fatal error: Allowed memory size of 15728640 bytes exhausted (tried to allocate 1024 bytes)
“ auslöst).
Standardmäßig wird das Profil in einer Datei mit dem Namen memprof.callgrind.*
in /tmp
oder C:WindowsTemp
gespeichert.
Die empfohlene Methode zur Visualisierung des Ergebnisses ist die Verwendung von Kcachegrind (unter Linux) oder Qcachegrind (unter MacOS, Windows). Google Perftools werden ebenfalls unterstützt. Siehe die Dokumentation von memprof_dump_callgrind()
und Varianten.
Die meisten Distributionen verfügen über ein kcachegrind
Paket, das installiert werden kann.
Zum Beispiel Ubuntu oder Debian:
sudo apt install kcachegrind
Andere Distributionen verfügen höchstwahrscheinlich auch über ein Paket, das zur Installation bereitsteht.
Verwenden Sie Homebrew: https://formulae.brew.sh/formula/qcachegrind
Laden Sie es von https://sourceforge.net/projects/qcachegrindwin/ herunter.
Die Profilerstellung wird beim Start der Anforderung aktiviert, wenn einer dieser Punkte zutrifft:
Die Umgebungsvariable MEMPROF_PROFILE
ist nicht leer
$_GET["MEMPROF_PROFILE"]
ist nicht leer
$_POST["MEMPROF_PROFILE"]
ist nicht leer
Die Variable MEMPROF_PROFILE
akzeptiert eine durch Kommas getrennte Liste von Flags.
Beispiele für gültige MEMPROF_PROFILE
-Werte:
1
: nicht leer: Profilerstellung ist aktiviert
dump_on_limit
: Profiling ist aktiviert, es erfolgt ein Dump bei Speicherbegrenzung
native
: Profilerstellung ist aktiviert, es werden native Zuordnungen profiliert
dump_on_limit,native
: Profiling ist aktiviert, erstellt ein Profil für native Zuordnungen und erstellt einen Dump bei Speicherbegrenzung
Liste gültiger Flags:
dump_on_limit
: Gibt das Profil im Callgrind-Format in /tmp
oder C:WindowsTemp
aus. Das Ausgabeverzeichnis kann mit der INI-Einstellung memprof.output_dir
geändert werden.
native
: Profiliert native malloc()
-Zuweisungen, nicht nur PHPs (Dies ist nicht threadsicher, siehe unten).
Memprof verfolgt standardmäßig keine nativen Zuweisungen, dies kann jedoch aktiviert werden, indem MEMPROF_PROFILE
auf native
gesetzt wird.
Native Zuweisungen sind Zuweisungen, die außerhalb des PHP-eigenen Speicherzuweisers vorgenommen werden. Normalerweise nehmen externe Bibliotheken wie libxml2 (in der DOM-Erweiterung verwendet) native Zuweisungen vor. PHP kann auch native Zuweisungen für persistente Ressourcen vornehmen.
Durch die Aktivierung der nativen Zuordnungsverfolgung werden diese Zuordnungen zusätzlich zu den PHP-eigenen Zuordnungen profiliert.
Beachten Sie, dass bei aktivierter nativer Nachverfolgung das Programm abstürzt, wenn eine native Bibliothek Threads verwendet, da die zugrunde liegenden Hooks nicht threadsicher sind.
Das Ausgabedateiformat wird mit der INI-Einstellung memprof.output_format
definiert. Die Optionen sind:
callgrind
(Standard)
pprof
Hinweis : Dies ist ab #101 möglicherweise nur verfügbar, wenn die Erweiterung aus dem Quellcode erstellt (und nicht mit pecl installiert) wird.
Gibt zurück, ob die Speicherprofilerstellung derzeit aktiviert ist (siehe oben).
Gibt zurück, ob Speicherprofilierung und welche Profilierungsfunktionen aktiviert sind (siehe oben).
Gibt das aktuelle Profil im Callgrind-Format aus. Das Ergebnis kann mit Tools wie KCacheGrind oder QCacheGrind visualisiert werden.
<phpmemprof_dump_callgrind(fopen("output", "w"));
Hier ist ein QcacheGrind-Screenshot:
Gibt das aktuelle Profil im pprof-Format aus.
<?phpmemprof_dump_pprof(fopen("profile.heap", "w"));
Die Datei kann mit dem pprof
Tool von google-perftools visualisiert werden. (Installationsanweisungen finden Sie unten.)
Kommentiertes Anrufdiagramm im Webbrowser oder in gv
anzeigen:
$ pprof --web profile.heap $ # or: $ pprof --gv profile.heap
Geben Sie eine Zeile pro Funktion aus, sortiert nach eigener Speichernutzung:
$ pprof --text profile.heap
pprof
Installationsanleitung: Ubuntu: apt install google-perftools
. Unter Ubuntu heißt das Tool google-pprof
, daher müssen Sie in den obigen Beispielen pprof
durch google-pprof
ersetzen.
Gibt ein Array zurück, das das aktuelle Profil darstellt.
<php$dump = memprof_dump_array();
Das Array stellt die folgenden Informationen bereit:
Inklusiver und exklusiver Speicher, der durch Funktionen verloren geht (es wird nur der Speicher gezählt, der noch nicht freigegeben ist, wenn memprof_dump_array aufgerufen wird)
Anzahl inklusiver und exklusiver Blöcke von Funktionen (Anzahl der Zuweisungen; es werden nur die Blöcke gezählt, die beim Aufruf von memprof_dump_array noch nicht freigegeben sind)
Die Daten werden in Aufrufstapeln dargestellt. Wenn eine Funktion von mehreren Stellen aus aufgerufen wird, kann auf diese Weise festgestellt werden, welcher Aufrufpfad den größten Speicherverlust verursacht hat
Array ( [memory_size] => 11578 [blocks_count] => 236 [memory_size_inclusive] => 10497691 [blocks_count_inclusive] => 244 [calls] => 1 [called_functions] => Array ( [main] => Array ( [memory_size] => 288 [blocks_count] => 3 [memory_size_inclusive] => 10486113 [blocks_count_inclusive] => 8 [calls] => 1 [called_functions] => Array ( [a] => Array ( [memory_size] => 4 [blocks_count] => 1 [memory_size_inclusive] => 10485825 [blocks_count_inclusive] => 5 [calls] => 1 [called_functions] => Array ( [b] => Array ( [memory_size] => 10485821 [blocks_count] => 4 [memory_size_inclusive] => 10485821 [blocks_count_inclusive] => 4 [calls] => 1 [called_functions] => Array ( [str_repeat] => Array ( [memory_size] => 0 [blocks_count] => 0 [memory_size_inclusive] => 0 [blocks_count_inclusive] => 0 [calls] => 1 [called_functions] => Array ( ) ) ) ) ) ) [memprof_dump_array] => Array ( [memory_size] => 0 [blocks_count] => 0 [memory_size_inclusive] => 0 [blocks_count_inclusive] => 0 [calls] => 1 [called_functions] => Array ( ) ) ) ) ) )
Gibt die Version der Erweiterung als Zeichenfolge zurück. Die Version kann mit version_compare() verglichen werden.
Die Erweiterungen können mit xdebug, blackfire oder anderen Erweiterungen in Konflikt stehen. Wenn das bei Ihnen der Fall ist, melden Sie es bitte.
Der aktuelle Zweig unterstützt PHP 7.1 bis PHP 8.
Der PHP5-Zweig unterstützt PHP 5.
Siehe INTERNALS.md