حل Allowed memory size exhausted في ووردبريس: تجربة 64M فعلية
ظهر عندك Allowed memory size exhausted ورفعت الحد، وبعد فترة رجع الخطأ على رقم اكبر؟ هذا غالبا دليل انك اخرت المشكلة وما عالجت السبب. لازم تعرف اي طلب وصل للسقف، واي كود كان يجمع بيانات من غير ما يحررها.
بمختبرنا حددنا PHP على 64 ميجابايت. طلب ووردبريس العادي وصل ذروة 32 ميجابايت ورجع 200. بعدها شغلنا مهمة تضيف كتل 2 ميجابايت لمصفوفة بلا نهاية، فوصلت الذروة 64 ميجابايت وفشل الطلب برمز 500. الاصلاح ما كان رفع الحد؛ عالجنا 50 وحدة، كل وحدة 1 ميجابايت، وحررناها مباشرة. اكتملت 50 ميجابايت من العمل بذروة 34 ميجابايت فقط.
الحالات الواقعية تظهر في دعم ووردبريس عن نمو غير محدود حتى بعد رفع الحد وفي نقاش ريديت عن خطأ الذاكرة عند الدخول. دليل تصحيح ووردبريس الرسمي يشرح تسجيل الاخطاء بعيدا عن الشاشة العامة.
النتيجة
- حد PHP: 64 ميجابايت.
- الطلب السليم: HTTP 200 وذروة 32 MiB.
- الحلقة: HTTP 500 وذروة 64 MiB.
- الخطأ حاول تخصيص 2,097,184 بايت اضافية.
- المعالجة المحدودة: 50 وحدة × 1 MiB، HTTP 200 وذروة 34 MiB.
خط الاساس

قياس الخط الاساس مهم. اذا ووردبريس يبدأ قريبا من السقف، حتى عملية طبيعية صغيرة ممكن تفشل. اما اذا المشكلة تظهر في طلب محدد، ركز على بياناته ومسار الكود بدل تعطيل كل شيء.
اعدنا الخطأ فعليا

تركنا احتياطا صغيرا من الذاكرة وحررناه في shutdown حتى نقدر نسجل نوع الخطأ والارقام بعد الفشل. اخفينا مسار الجهاز من التقرير. ما شغلنا المهمة على الموقع العام ولا داخل عملية طويلة مشتركة.
اصلحنا طريقة المعالجة

المهم مش حجم كل البيانات على القرص، بل كم منها موجود في الذاكرة بنفس اللحظة. القراءة على دفعات، pagination، generators، وstreaming بتخلي الاستهلاك مربوطا بحجم الدفعة بدل حجم الملف كله.
فيديو توثيق التجربة الفعلية
هذا تسجيل شاشة صامت ومتواصل للاختبار وهو يحدث داخل بيئة محلية معزولة. تظهر الخطوات والنتائج الفعلية لحظة التنفيذ، من غير تركيب صور ثابتة.
اقرأ رسالة الخطأ صح
الرقم الاول هو السقف المسموح للعملية، والرقم الثاني هو التخصيص الذي فشل. الملف والسطر هما مكان آخر محاولة، مش دايما اصل التسريب. ممكن core يفشل وهو يحاول 20KB لان إضافة استهلكت كل المساحة قبلها.
خطة العزل
- سجل URL والوقت ونوع العملية والمستخدم.
- اقرأ اول fatal كامل مع stack trace اذا متوفر.
- قارن memory_limit في الويب وCLI، لانهم ممكن يستخدموا php.ini مختلفا.
- اعد الطلب على staging ببيانات مماثلة.
- عطل المسبب المحتمل او ارجع نسخته، ثم قس الذروة.
- افحص حلقات recursion والاستعلامات الكبيرة وقراءة ملفات كاملة.
- قلل batch size وحرر المراجع بين الدفعات.
- ارفع الحد بشكل معقول فقط اذا الحمل شرعي ومقاس.
اسباب شائعة
- استيراد آلاف السجلات في مصفوفة واحدة.
- بناء JSON ضخم قبل ارساله.
- قراءة ملف backup او log كاملا.
- استعلام يجلب كل posts وmeta بلا حدود.
- حلقة او recursion ما لها شرط توقف صحيح.
- كاش داخل الطلب ينمو مع كل عنصر.
- تشغيل عدة إضافات ثقيلة في نفس admin request.
متى ترفع الحد؟
اذا قست الذروة وعرفت ان المهمة الشرعية تحتاج مثلا 150 MiB على دفعات معقولة، وحدك 128M، رفعه إلى 256M ممكن يكون صحيحا. اما اذا الاستهلاك ينمو كل ما تكبر البيانات او وصل 3GB، الرفع يخفي خللا وقد يجعل الخادم كله يدخل OOM.
فرق PHP memory_limit عن ذاكرة الخادم
وجود 16GB RAM لا يعني ان كل PHP worker يقدر ياخذها. كل عملية لها memory_limit، والخادم يشغل عدة workers وقاعدة بيانات وكاش. رفع كل worker إلى 1GB ممكن يسمح لعدد قليل من الطلبات باستهلاك الجهاز كله.
لا تعرض fatal للزوار
سجل الخطأ في ملف غير عام او نظام logs، وخلي WP_DEBUG_DISPLAY مغلقا في الانتاج. رسالة fatal قد تكشف مسارات واسماء إضافات. في تجربتنا ظهر النص لانها نسخة محلية ثم اخفينا المسار من الصور المنشورة.
حدود تجربتنا
المهمة مصممة عمدا لتستهلك الذاكرة، وما تمثل إضافة بعينها. الارقام خاصة بنسخة PHP المحلية. اللي يمكن تعميمه هو الفرق بين تراكم كل الكتل ومعالجة كتلة واحدة ثم تحريرها.
الخلاصة
طلبنا وصل سقف 64M وفشل 500 عندما جمع البيانات بلا حد. نفس البيئة عالجت 50M من العمل بذروة 34M بعد تقسيمه وتحرير كل كتلة. ارفع الذاكرة عند الحاجة المقاسة، لكن اصلح النمو غير المحدود اولا.