2012-01-12 6 views
5

Sto eseguendo il codice PHP di seguito dalla riga di comando. Il problema è, il suo consumo di memoria molto più di quello che dovrebbe essere. Non posso, per la vita di me, capire dove si consuma la memoria.Problema di perdita di memoria di 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);   
     } 

Secondo me, la memoria consumata da mio script dovrebbe rimanere più o meno costante dopo ogni iterazione del ciclo. Qualsiasi memoria consumata da $scraper->scrapeClassInfo() deve essere liberata quando i suoi membri escono dall'ambito.

Questo è il file di output che ottengo. Per ragioni di brevità, sto mostrando ogni 10 linea dell'uscita:

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 

Infine, per quanto posso vedere, che cosa sta facendo $scraper->scrapeClassInfo() non dovrebbe essere in realtà il colpevole, ma solo nel caso, qui è il codice:

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

il metodo chiamato nell'ultima riga, str_get_html() è un membro della Simple HTML DOM Parser

nel caso in cui la materia, questo è come io chiamo il mio script:

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

risposta

3

OK, ho capito. Apparentemente, è un bug di cui soffre tutta la versione di PHP precedente alla 5.3. L'impostazione di CURLOPT_RETURNTRANSFER a true causa massicce perdite di memoria.

mi corse lo script di nuovo, questa volta invocando il PHP 5.3 binario:

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

E il file di output si legge:

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 

Ora che è quello che sto parlando! Impronta di memoria perfettamente costante.

+0

Qual è l'errore? –

+0

Quando ho scritto "Impostazione CURLOPT_RETURNTRANSFER su true" intendevo scrivere "L'impostazione di CURLOPT_RETURNTRANSFER su true causa massicce perdite di memoria". Modificato. – xbonez

+0

Aha. +1 per la spiegazione. –

1

Ho trovato quanto segue nel codice.

  1. Rimuovere curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) come non si è catturarlo.
  2. Non chiudere la maniglia di arricciatura. Riutilizzalo.

Per risolvere il problema attuale è possibile eseguire lo script php con una maggiore memroy_limit

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

1G significa 1 Gigabyte.

+0

Grazie. Sicuramente nella giusta direzione. Ho provato a rimuovere 'CUROPT_RETURNTRANSFER', ma nell'ultima richiesta di arricciatura che ho fatto, avevo bisogno di lasciarlo e quindi avevo ancora il problema della memoria. Ad ogni modo, vedi la mia risposta qui sotto. – xbonez