Frage

Dies ist eine für alle von euch Lehre Benutzer ist da draußen. Ich habe einen PHP CLI-Daemon-Prozess, der eine Tabelle alle n Sekunden prüft Einträge zu finden, die nicht verarbeitet wurden. Es ist im Grunde ein FIFO. Wie auch immer, ich überschreiten die Erinnerung immer zugewiesen becuase Lehre PHP entbindet nicht die Ressourcen. Zur Bekämpfung dieses Problems ist es frei für das Query-Objekt zur Verfügung stellt. Ich kann nicht scheinen, um es aber funktionieren. Hier ist der Code:

 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();

Irgendwelche Ideen, was ich tue falsch?

EDIT: Ich bin mit 1.0.3

EDIT: Ich habe alle unten stehenden Vorschläge ausprobiert. Ich war sehr zuversichtlich für unset() wie ich es dort hatte, bevor ich free() gefunden.

Hier mehr des Codes ist, um möglicherweise in jeder Hilfe zu unterstützen. Bevor Sie das Öffnen und Schließen der Verbindung in Frage wird es Daemon Prozess sein, der Kinder und ich habe erlebt die Verbindung laicht muss eindeutig sein.

  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

Einige Beispielausgabe:

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
War es hilfreich?

Lösung

Das Problem ist, dass free() nicht die Lehre Objekte aus dem Speicher nicht entfernt, sondern beseitigt nur die zirkulären Verweise auf diesen Objekten, es möglich, dass der Garbage Collector Bereinigungs diese Objekte zu machen. Bitte finden Sie unter 23,6 Freie Objekte in der Lehre Handbuch :

  

Ab Version 5.2.5, PHP ist nicht in der Lage   Objektgraphen zu Müll sammeln,   haben zirkuläre Referenzen, z.B. Elternteil   hat einen Verweis auf ein Kind, die aufweist   Verweis auf Parent. Seit vielen   Lehre Modell-Objekte haben eine solche   Beziehungen, wird PHP nicht frei, ihre   Speicher, auch wenn die Objekte gehen aus   Anwendungsbereich.

     

Für die meisten PHP-Anwendungen, diese   Problem ist von geringer Bedeutung,   da PHP-Skripte sind in der Regel sein   kurzlebig. Langlebigeren Skripte,   z.B. Massendaten Importeure und   Exporteure können über genügend Arbeitsspeicher ausgeführt   es sei denn, Sie manuell den Kreis brechen   Referenzketten. Lehre bietet eine   free () Funktion auf Doctrine_Record,   Doctrine_Collection und   Doctrine_Query, die die beseitigt   zirkuläre Referenzen auf diese Objekte,   befreien sie für Müll up   Sammlung.

Die Lösung sollte sein, das unset() Objekt $query free() nach der Verwendung:

$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

Andere Tipps

Doctrine_Query hat auch einen kostenlosen () -Methode, zur Zeit sind Sie gerade telefonieren kostenlos () auf Ihrem Doctrine_Collection, zum Beispiel versuchen:

 $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();

Keine Erfahrung mit Lehre (nur ein gewisses Interesse, wie ich es in dieser Woche-Ende entdeckt ...), so nehmen oder meine Vermutung verlassen ... ^ _ ^

Ich würde versuchen, die Erstellung der Abfrage von seinem ausführen Teil trennen:

$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();

Nicht sicher, was zurückkehrt ausführen, aber nur für den Fall, es ist ein Versuch wert ... Es sei denn, jemand einen aufgeklärten Rat hat! :-P

Versuchen $ query-> kostenlos (true);

(?)

Ich glaube, ich könnte nur PDO nicht benutzen will für die Back-End-Teile, die wirklich die ORM sowieso nicht brauchen, da es nicht so viele Abfragen sind. Ich wollte wirklich nur einen einzigen Weg, um mit der DB über alle meine apps in diesem System zu interagieren. Vielleicht werde ich etwas mehr Gedanken.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top