php-memprof هو امتداد سريع ودقيق لملفات تعريف الذاكرة لـ PHP ويمكن استخدامه للعثور على سبب تسرب الذاكرة.
يتتبع الامتداد تخصيص وتحرير كتل الذاكرة للإبلاغ عن مقدار الذاكرة المسربة بواسطة كل وظيفة أو طريقة أو ملف في البرنامج.
تقارير الذاكرة غير المحررة في نقاط تعسفية في البرنامج
مقالب الملف الشخصي بتنسيقات callgrind أو pprof أو المصفوفة الأولية
يمكن تتبع الذاكرة المخصصة بواسطة PHP نفسها بالإضافة إلى malloc الأصلي
يعتمد php-memprof على libjudy وsys/queue.h.
في التوزيعات المبنية على دبيان، يمكن تثبيت التبعيات باستخدام:
# Debian or Ubuntu: apt install libjudy-dev
على جبال الألب:
# Alpine apk add judy-dev bsd-compat-headers
على نظام التشغيل MacOS:
# install libjudy dependency: brew install traildb/judy/judy
تأكد من تثبيت التبعيات، ثم:
pecl install memprof
على نظام MacOS: JUDY_DIR=$(brew --prefix Traildb/judy/judy) pecl install memprof
ملاحظة: إذا تم تثبيت libjudy في مسار غير قياسي (ليس /usr أو /usr/local)، فيرجى استخدام طريقة التثبيت اليدوي أدناه.
تأكد من تثبيت التبعيات، ثم:
قم بتنزيل المصدر وقم بتشغيل الأوامر التالية في الدليل المصدر:
phpize ./configure make make install
ملاحظة: إذا تم تثبيت libjudy في مسار غير قياسي (وليس /usr أو /usr/local)، فيمكنك تحديده على النحو التالي:
./configure --with-judy-dir=/opt/homebrew/Cellar/judy/1.0.5
قد يفضل مستخدمو Arch Linux تثبيت حزمة php-memprof غير الرسمية باستخدام makepkg أو مساعد AUR المفضل لديهم. إذا كنت تستخدم yay ، على سبيل المثال:
yay -S php-memprof
الرجاء الإبلاغ عن أية مشكلات تتعلق بهذه الحزمة على صفحة AUR الخاصة بها.
يمكن تحميل الامتداد في سطر الأوامر، لبرنامج نصي واحد فقط:
php -dextension=memprof.so script.php
أو بشكل دائم، في php.ini:
extension=memprof.so
لا يحتوي الامتداد على أي حمل عند عدم إنشاء ملفات تعريف، لذلك يمكن تحميله افتراضيًا في بيئات التطوير.
إن أبسط طريقة لاستخدام memprof هي السماح له بحفظ ملف تعريف الذاكرة عند تجاوز حد ذاكرة البرنامج.
dump_on_limit يتم تمكين التوصيف في وضع dump_on_limit عند بدء تشغيل الطلب عندما يكون أي مما يلي صحيحًا:
متغير البيئة MEMPROF_PROFILE يساوي dump_on_limit
$_GET["MEMPROF_PROFILE"] يساوي dump_on_limit
$_POST["MEMPROF_PROFILE"] يساوي dump_on_limit
بالنسبة للنصوص البرمجية لسطر الأوامر، يمكننا تعيين متغير البيئة:
MEMPROF_PROFILE=dump_on_limit php test.php
بالنسبة لنصوص الويب، يمكننا تعيين المتغير $_GET :
curl http://127.0.0.1/test.php?MEMPROF_PROFILE=dump_on_limit
أو المتغير $_POST :
curl -d MEMPROF_PROFILE=dump_on_limit http://127.0.0.1/test.php
ملاحظة: يمكن استدعاء الدالة
memprof_enabled_flags()للتحقق مما إذا كان إنشاء ملفات التعريف ممكّنًا حاليًا في وضعdump_on_limit.
في هذا الوضع، سيحفظ memprof ملف التعريف تلقائيًا إذا تجاوز البرنامج حد الذاكرة (عندما يقوم PHP بتشغيل خطأ مثل Fatal error: Allowed memory size of 15728640 bytes exhausted (tried to allocate 1024 bytes) ).
افتراضيًا، يتم حفظ ملف التعريف في ملف باسم memprof.callgrind.* في /tmp أو C:WindowsTemp .
الطريقة الموصى بها لتصور النتيجة هي استخدام Kcachegrind (على Linux) أو Qcachegrind (على MacOS وWindows). كما يتم دعم Google Perftools. راجع وثائق memprof_dump_callgrind() والمتغيرات.
تحتوي معظم التوزيعات على حزمة kcachegrind جاهزة للتثبيت.
على سبيل المثال، أوبونتو أو دبيان:
sudo apt install kcachegrind
من المرجح أن تحتوي التوزيعات الأخرى على حزمة جاهزة للتثبيت أيضًا.
استخدم البيرة المنزلية: https://formulae.brew.sh/formula/qcachegrind
قم بتنزيله من https://sourceforge.net/projects/qcachegrindwin/
يتم تمكين إنشاء ملفات التعريف عند بدء تشغيل الطلب عندما يكون أي مما يلي صحيحًا:
متغير البيئة MEMPROF_PROFILE ليس فارغًا
$_GET["MEMPROF_PROFILE"] ليس فارغًا
$_POST["MEMPROF_PROFILE"] ليس فارغًا
يقبل المتغير MEMPROF_PROFILE قائمة من العلامات مفصولة بفواصل.
أمثلة على قيم MEMPROF_PROFILE الصالحة:
1 : غير فارغ: تم تمكين التنميط
dump_on_limit : تم تمكين التوصيف، وسيتم تفريغه على حد الذاكرة
native : تم تمكين إنشاء ملفات التعريف، وسيتم تحديد تخصيصات أصلية
dump_on_limit,native : تم تمكين إنشاء ملفات التعريف، وسيتم تخصيص ملفات تعريف التخصيصات الأصلية، وسيتم تفريغ حد الذاكرة
قائمة الأعلام الصالحة:
dump_on_limit : سيتم تفريغ ملف التعريف بتنسيق callgrind في /tmp أو C:WindowsTemp . يمكن تغيير دليل الإخراج باستخدام الإعداد memprof.output_dir ini.
native : سيتم تخصيص تخصيصات malloc() الأصلية، وليس فقط PHP (هذا ليس مؤشر ترابط آمن، انظر أدناه).
لا يقوم Memprof بتتبع عمليات التخصيص الأصلية بشكل افتراضي، ولكن يمكن تمكين ذلك عن طريق تعيين MEMPROF_PROFILE إلى native .
التخصيصات الأصلية هي التخصيصات التي تتم خارج مُخصص الذاكرة الخاص بـ PHP. عادةً، تقوم المكتبات الخارجية مثل libxml2 (المستخدمة في ملحق DOM) بإجراء عمليات تخصيص أصلية. يمكن لـ PHP أيضًا إجراء تخصيصات أصلية للموارد الدائمة.
سيؤدي تمكين تتبع التخصيص الأصلي إلى تحديد هذه التخصيصات بالإضافة إلى تخصيصات PHP الخاصة.
لاحظ أنه عند تمكين التتبع الأصلي، سيتعطل البرنامج إذا كانت المكتبة الأصلية تستخدم سلاسل الرسائل، لأن الخطافات الأساسية ليست آمنة لسلاسل الرسائل.
يتم تعريف تنسيق ملف الإخراج باستخدام الإعداد memprof.output_format ini. الخيارات هي:
callgrind (افتراضي)
pprof
ملاحظة : قد يكون هذا متاحًا فقط عندما يتم إنشاء الامتداد من المصدر (وليس مثبتًا مع pecl)، اعتبارًا من رقم 101.
إرجاع ما إذا كان ملف تعريف الذاكرة ممكّنًا حاليًا (انظر أعلاه).
إرجاع ما إذا كان قد تم تمكين ملفات تعريف الذاكرة وميزات ملفات التعريف (انظر أعلاه).
تفريغ ملف التعريف الحالي بتنسيق callgrind. يمكن تصور النتيجة باستخدام أدوات مثل KCacheGrind أو QCacheGrind.
<phpmemprof_dump_callgrind(fopen("output", "w"));فيما يلي لقطة شاشة لـ QcacheGrind:
تفريغ ملف التعريف الحالي بتنسيق pprof.
<?phpmemprof_dump_pprof(fopen("profile.heap", "w")); يمكن تصور الملف باستخدام أداة pprof الخاصة بـ google-perftools. (انظر أدناه للحصول على تعليمات التثبيت.)
عرض الرسم البياني للمكالمات المشروحة في متصفح الويب أو في gv :
$ pprof --web profile.heap $ # or: $ pprof --gv profile.heap
إخراج سطر واحد لكل وظيفة، مرتبة حسب استخدام الذاكرة الخاصة:
$ pprof --text profile.heap
pprof : أوبونتو: apt install google-perftools . في نظام Ubuntu، تُسمى الأداة google-pprof ، لذا تحتاج إلى استبدال pprof بـ google-pprof في الأمثلة أعلاه.
إرجاع مصفوفة تمثل ملف التعريف الحالي.
<php$dump = memprof_dump_array();
تعرض المصفوفة المعلومات التالية:
الذاكرة الشاملة والحصرية التي تم تسريبها بواسطة الوظائف (حساب الذاكرة التي لم يتم تحريرها بعد عند استدعاء memprof_dump_array)
عدد الكتل الشاملة والحصرية للوظائف (عدد التخصيصات؛ حساب فقط الكتل التي لم يتم تحريرها بعد عند استدعاء memprof_dump_array)
يتم تقديم البيانات في مكدسات المكالمة. بهذه الطريقة، إذا تم استدعاء دالة من أماكن متعددة، فمن الممكن معرفة مسار الاستدعاء الذي تسبب في تسرب معظم الذاكرة
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 ( ) ) ) ) ) )
إرجاع إصدار الامتداد كسلسلة. يمكن مقارنة الإصدار بـ version_compare().
قد تتعارض الملحقات مع xdebug أو blackfire أو ملحقات أخرى. إذا كان هذا هو الحال بالنسبة لك، يرجى الإبلاغ عنه.
يدعم الفرع الحالي PHP 7.1 إلى PHP 8.
فرع php5 يدعم PHP 5.
انظر INTERNALS.md