2008-11-17 11 views
5

Este es uno para cualquiera de ustedes usuarios de Doctrine. Tengo un proceso de daemon PHP CLI que comprueba una tabla cada n segundos para encontrar entradas que no se han procesado. Es básicamente un FIFO. De todos modos, siempre excedo la memoria asignada a PHP porque Doctrine no libera sus recursos. Para combatir este problema, proporciona gratis para el objeto de consulta. Parece que no puedo hacer que funcione. Aquí está el código:¿Por qué no funciona el PHP Doctine's free()?

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

¿Alguna idea de lo que estoy haciendo mal?

EDIT: Estoy usando 1.0.3

EDIT: He intentado todas las sugerencias a continuación. Tenía mucha esperanza para unset() ya que lo tenía allí antes de encontrar free().

Aquí hay más del código que posiblemente ayude en cualquier ayuda. Antes de cuestionar la apertura y el cierre de la conexión, será un proceso demoníaco que engendrará hijos y, como he experimentado, la conexión debe ser única.

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 

un ejemplo de salida:

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 

Respuesta

4

El problema es, que free() no elimina los objetos Doctrina de la memoria, pero sólo elimina las referencias circulares en esos objetos, por lo que es posible que el recolector de basura para la limpieza de aquellos objetos. Por favor, vea en el 23.6 Free ObjectsDoctrine manual:

partir de la versión 5.2.5, PHP no es capaz a recoger la basura gráficos de objetos que tienen referencias circulares, por ejemplo Parent tiene una referencia a Child que tiene una referencia para Parent. Dado que muchos objetos del modelo de doctrina tienen tales relaciones , PHP no liberará su memoria incluso cuando los objetos salgan del alcance .

Para la mayoría de las aplicaciones PHP, este problema es de poca importancia, ya que scripts PHP tienden a ser de corta duración. Guiones más antiguos, p. los importadores de datos masivos y los exportadores , pueden quedarse sin memoria a menos que rompa manualmente las cadenas de referencia circulares.Doctrina proporciona una función libre() en Doctrine_Record, Doctrine_Collection y Doctrine_Query que elimina las referencias circulares sobre esos objetos, liberándolos para la recolección de basura .

La solución debe ser a unset() el objeto $query después de usar 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 
+0

Tenía mucha esperanza para eso. Me había desarmado antes de que descubriera que era libre y luego lo borré apresuradamente. Incluso con eso de nuevo no está funcionando. –

0

Sin experiencia con Doctrina (sólo algunas de interés como descubrí que este fin de semana ...), por lo que tomar o dejar mi conjetura ...^_^

me gustaría tratar de separar la creación de consultas de su parte ejecutar:

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

No estoy seguro que ejecutar las devoluciones, pero por si acaso, vale la pena intentarlo ... ¡a menos que alguien tenga un consejo más ilustrado! :-P

+0

Soy un n00b completa a mí mismo. Tenía la misma idea, pero no funcionó de manera diferente. –

0

Pruebe $ query-> free (true);

(?)

+0

Disculpa, probablemente debería haber esbozado lo que en realidad he intentado ya. Esa fue la primera vez, pero fue en vano. –

0

creo que sólo podría ir a usar DOP para las piezas de back-end que realmente no necesita el ORM de todos modos ya que no hay muchas consultas Realmente quería tener una única forma de interactuar con el DB en todas mis aplicaciones en este sistema. Tal vez voy a pensar un poco más.

1

Doctrine_Query también tiene un método libre(), en el momento en que se acaba de llamadas gratis() en su Doctrine_Collection, por ejemplo, tratar:

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