سؤال

وهذا هو واحد هو لأحدكم المستخدمين مذهب هناك. لدي عملية الخفي PHP CLI أن يتحقق على طاولة كل n ثانية للعثور على إدخالات التي لم يتم معالجتها. انها في الاساس عملية FIFO. على أي حال، وأنا دائما تتجاوز الذاكرة المخصصة PHP بيكوس عقيدة لا تحريرها في الموارد. لمكافحة هذه المشكلة أنها توفر مجانا لكائن الاستعلام. أنا لا يمكن أن يبدو لانجاحها بالرغم من ذلك. هنا هو رمز:

 22     print "You are using " . (memory_get_usage() / 1024). "\n";
 23     $query = Doctrine_Query::create()
 24                 ->from('SubmissionQueue s')
 25                 ->where('s.time_acted_on IS NULL')
 26                 ->orderby('s.time_queued')
 27                 ->limit(1)
 28                 ->execute();
 29     print $query[0]->time_queued . "\n";
 30     $query->free();

وأي أفكار ما أقوم به خطأ؟

وتحرير: أنا باستخدام 1.0.3

تحرير: لقد حاولت كل الاقتراحات أدناه. أنا متفائل جدا لunset() كما كان في هناك قبل وجدت free().

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

  1 <?php
  2
  3 require_once('/usr/local/lib/php/Doctrine/lib/Doctrine.php');
  4
  5 spl_autoload_register(array('Doctrine', 'autoload'));
  6
  7 $manager = Doctrine_Manager::getInstance();
  8 $manager->setAttribute('model_loading','conservative');
  9 Doctrine::loadModels('lib/model/master');
 10
 11 while(1){
 12     print "You are using " . intval(memory_get_usage() / 1024) . "\n";
 13     $manager->connection('********************************************','master');
 14     $query = Doctrine_Query::create()
 15                 ->from('SubmissionQueue s')
 16                 ->where('s.time_acted_on IS NULL')
 17                 ->orderby('s.time_queued')
 18                 ->limit(1)
 19                 ->execute();
 20     print "[" . $query[0]->time_queued . "]\n";
 21     $query->free();
 22     unset($query);
 23     $query = null;
 24     $manager->closeConnection(Doctrine_Manager::getInstance()->getConnection('master'));
 25     sleep(5);
 26 }
 27

وبعض إخراج نموذج:

You are using 14949KB
[2008-11-17 13:59:00]
You are using 14978KB
[2008-11-17 13:59:00]
You are using 15007KB
[2008-11-17 13:59:00]
You are using 15035KB
[2008-11-17 13:59:00]
You are using 15064KB
[2008-11-17 13:59:00]
You are using 15093KB
[2008-11-17 13:59:00]
You are using 15121KB
[2008-11-17 13:59:00]
You are using 15150KB
[2008-11-17 13:59:00]
You are using 15179KB
[2008-11-17 13:59:00]
You are using 15207KB
[2008-11-17 13:59:00]
You are using 15236KB
[2008-11-17 13:59:00]
You are using 15265KB
[2008-11-17 13:59:00]
You are using 15293KB
[2008-11-17 13:59:00]
You are using 15322KB
هل كانت مفيدة؟

المحلول

والمشكلة هي أن free() لا يزيل الكائنات مذهب من الذاكرة، ولكن فقط يزيل المراجع الدائرية على هذه الكائنات، مما يجعل من الممكن لجمع القمامة لتنظيف هذه الكائنات. يرجى الاطلاع على 23.6 الأجسام الحرة في دليل عقيدة :

<اقتباس فقرة>   

واعتبارا من الإصدار 5.2.5، PHP غير قادر   إلى القمامة جمع الرسوم البيانية الكائن الذي   لديها مراجع دائرية، على سبيل المثال الأبوين   لديه اشارة الى الطفل الذي لديه   إشارة إلى الأم. منذ كثير   كائنات نموذج عقيدة لديها مثل هذه   العلاقات، سوف PHP لا فراغهم   الذاكرة حتى عندما تسير الأشياء من   النطاق.

     

لمعظم التطبيقات PHP، هذا   المشكلة هي نتيجة تذكر،   منذ مخطوطات PHP تميل إلى أن تكون   قصير الأمد. البرامج النصية الأطول عمرا،   مثلا المستوردين البيانات كبيرة الحجم و   مصدرين، يمكن أن ينفد من الذاكرة   إلا إذا كنت يدويا كسر التعميم   سلاسل المرجعية. يوفر عقيدة ل   حرة وظيفة () على Doctrine_Record،   Doctrine_Collection، و   Doctrine_Query الذي يلغي   المراجع الدائرية على هذه الكائنات،   الافراج عنها لالقمامة   جمع.

وينبغي أن يكون الحل لunset() الكائن $query بعد استخدام free():

$query = Doctrine_Query::create()
            ->from('SubmissionQueue s')
            ->where('s.time_acted_on IS NULL')
            ->orderby('s.time_queued')
            ->limit(1);
$query->execute();
print $query[0]->time_queued . "\n";
$query->free();
unset($query); // perhaps $query = null; will also work

نصائح أخرى

له

وDoctrine_Query أيضا وسيلة مجانا ()، في هذه اللحظة كنت فقط يدعو مجانا () على Doctrine_Collection الخاصة بك، على سبيل المثال، في محاولة:

 $query = Doctrine_Query::create()
             ->from('SubmissionQueue s')
             ->where('s.time_acted_on IS NULL')
             ->orderby('s.time_queued')
             ->limit(1);
 $results = $query->execute();
 print $results[0]->time_queued . "\n";

 $results->free();
 $query->free();

وأي خبرة مع عقيدة (فقط بعض الاهتمام كما اكتشفت انها نهاية هذا الأسبوع ...)، حتى تأخذ أو ترك تخميني ... ^ _ ^

وأود أن محاولة فصل إنشاء الاستعلام من جزء تنفيذ لها:

$query = Doctrine_Query::create()
            ->from('SubmissionQueue s')
            ->where('s.time_acted_on IS NULL')
            ->orderby('s.time_queued')
            ->limit(1);
$query->execute();
print $query[0]->time_queued . "\n";
$query->free();

ولست متأكدا ما تنفيذ العودة، ولكن فقط في حالة، الأمر يستحق المحاولة ... ما لم يكن شخص ما لديه المزيد من النصائح المستنيرة! :-P

وحاول $ query-> مجانا (صحيح)؛

و(؟)

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top