2012-01-12 7 views
5

Estoy ejecutando el código PHP a continuación desde la línea de comandos. El problema es que su consumo de memoria es mucho más de lo que debería ser. No puedo, por mi vida, descubrir dónde se está consumiendo la memoria.Problema de fuga de memoria de script PHP

for ($i=0;$i<100;$i++) 
     { 
      $classObject = $classObjects[$i];      

      echo $i . " : " . memory_get_usage(true) . "\n"; 
      $classDOM = $scraper->scrapeClassInfo($classObject,$termMap,$subjectMap);   
      unset($classDOM);   
     } 

Según yo, la memoria consumida por mi guión debe permanecer más o menos constante después de cada iteración del bucle. Cualquier memoria consumida por $scraper->scrapeClassInfo() se debe liberar cuando sus miembros quedan fuera del alcance.

Este es el archivo de salida que obtengo. En aras de la brevedad, estoy mostrando cada décima línea de la salida:

0 : 5767168 
10 : 12058624 
20 : 18350080 
30 : 24903680 
40 : 30932992 
50 : 37748736 
60 : 43778048 
70 : 49807360 
80 : 55836672 
90 : 62914560 
97 : 66846720 

Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 44 bytes) in /home/content/60/8349160/html/drexel/simple_html_dom.php on line 1255 

Finalmente, en lo que puedo ver, lo está haciendo muy $scraper->scrapeClassInfo() no debe ser el culpable, pero por si acaso, aquí el código:

function scrapeClassInfo($class,$termMap,$subjectMap) 
     { 
      $ckfile = tempnam ("/tmp", "CURLCOOKIE"); 
      $ckfile2 = tempnam ("/tmp", "CURLCOOKIE2"); 
      $ckfile3 = tempnam ("/tmp", "CURLCOOKIE3");   

      $termpage = $termMap[$class['termcode']]; 
      $subjectpage = $subjectMap[$class['subjectcode']]; 
      $classpage = $class['classlink']; 

      //hit the main page and get cookie 
      $ch = curl_init(); 
      curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile); 
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
      curl_setopt($ch, CURLOPT_URL, $this->mainURL); 
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
      curl_exec($ch); 
      curl_close($ch); 

      //hit the term page and get cookie 
      $ch = curl_init(); 
      curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile); 
      curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile2); 
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
      curl_setopt($ch, CURLOPT_URL, $termpage); 
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
      curl_exec($ch); 
      curl_close($ch); 

      //hit the subject page and get cookie 
      $ch = curl_init(); 
      curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile3); 
      curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile2); 
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
      curl_setopt($ch, CURLOPT_URL, $subjectpage); 
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
      curl_exec($ch); 
      curl_close($ch); 

      //hit the class page and scrape 
      $ch = curl_init();    
      curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile3); 
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
      curl_setopt($ch, CURLOPT_URL, $classpage); 
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
      $result = curl_exec($ch); 
      curl_close($ch); 

      return str_get_html($result); 
     } 

el método llamado en la última línea, str_get_html() es miembro de Simple HTML DOM Parser

en caso de que la materia, así es como yo estoy llamando a mi guión:

/usr/local/php5/bin/php index.php 2>&1 1>output

Respuesta

3

Muy bien, lo descubrí. Aparentemente, es un error que sufren todas las versiones de PHP anteriores al 5.3. Establecer CURLOPT_RETURNTRANSFER a true provoca pérdidas de memoria masivas.

que ejecutar el script de nuevo, esta vez invocando el php 5.3 binaria:

/web/cgi-bin/php5_3 index.php 2>&1 1>output 

Y el archivo de salida se lee:

0 : 6291456 
10 : 9437184 
20 : 10747904 
30 : 11534336 
40 : 11534336 
50 : 11534336 
60 : 11534336 
70 : 11534336 
80 : 11534336 
90 : 11534336 
99 : 11534336 
152.74998211861 sec 

Ahora eso es lo que estoy hablando! Huella de memoria perfectamente constante.

+0

¿Cuál es el error? –

+0

Cuando escribí "Configuración de CURLOPT_RETURNTRANSFER en true" quise escribir "Establecer CURLOPT_RETURNTRANSFER en verdadero provoca pérdidas masivas de memoria". Editado – xbonez

+0

Aha. +1 para la explicación. –

1

Encontré lo siguiente en su código.

  1. Como eliminar curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) no lo está capturando.
  2. No cierre la palanca de curl. Reutilízalo.

Como solución actual puede ejecutar el script PHP con una mayor memroy_limit

$ php -d memory_limit=1G /path/to/script 

1G significa 1 Gigabyte.

+0

Gracias. Definitivamente en la dirección correcta. Intenté eliminar 'CUROPT_RETURNTRANSFER', pero en la última solicitud de curl que hice, tuve que dejarlo y todavía tenía el problema de memoria. De todos modos, mira mi respuesta a continuación. – xbonez