2012-01-12 86 views
5

我從命令行運行下面的PHP代碼。問題是,它的內存消耗遠遠超過它應該是的。在我的生活中,我無法弄清楚內存消耗的位置。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);   
     } 

根據我的說法,我的腳本所消耗的內存應該在循環的每次迭代後都保持不變。當其成員超出範圍時,應該釋放由$scraper->scrapeClassInfo()消耗的任何內存。

這是我得到的輸出文件。爲了簡便起見,我顯示輸出的每10號線:

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 

最後,就我所看到的,是什麼$scraper->scrapeClassInfo()是做真的不應該是罪魁禍首,但以防萬一,在這裏是代碼:

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

稱爲最後一行的方法,str_get_html()Simple HTML DOM Parser

一個成員都應該有關係,這是我如何我打電話我的腳本:

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

回答

3

好吧,想通了。顯然,它是PHP 5.3之前的所有版本都受到影響的錯誤。將CURLOPT_RETURNTRANSFER設置爲true會導致大量內存泄漏。

我再次運行腳本,這一次調用PHP 5.3二進制:

​​

和輸出文件讀取:

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 

現在這就是我說的!完美的內存佔用。

+0

什麼是錯誤? – 2012-01-12 14:16:57

+0

當我寫「將CURLOPT_RETURNTRANSFER設置爲true」時,我打算寫「將CURLOPT_RETURNTRANSFER設置爲true會導致大量內存泄漏」。編輯。 – xbonez 2012-01-12 14:18:31

+0

啊哈。 +1的解釋。 – 2012-01-12 14:29:26

1

我在代碼中發現了以下內容。

  1. 刪除curl_setopt($ch, CURLOPT_RETURNTRANSFER, true)因爲您沒有捕獲它。
  2. 不要關閉卷曲手柄。重新使用它。

作爲當前的解決方法,你可以用更高的memroy_limit

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

1G運行PHP腳本意味着1千兆字節。

+0

謝謝。絕對是在正確的方向。我嘗試刪除'CUROPT_RETURNTRANSFER',但是在最後的捲曲請求中,我需要離開它,所以我仍然遇到內存問題。無論如何,請參閱下面的答案。 – xbonez 2012-01-12 14:16:11