2014-10-09 57 views
0

我的php腳本停止運行,因爲它內存不足。 這裏是我的代碼:php mysql循環內存泄漏?

$files = array_diff(scandir($dir_name), array('..', '.')); 
if (!empty($files)) 
{ 
    foreach ($files as $file) 
    { 
     if (pathinfo($file, PATHINFO_EXTENSION) == "csv") 
     { 
      $fp = fopen($dir_name.$file, 'r'); 
      while (($line = fgetcsv($fp, 0, $delimiter)) !== FALSE) 
       insert_update(array_map('addslashes', $line), $connect_id); 
      fclose($fp); 
     } 
    } 
    mysqli_close($connect_id); 
} 

我並運行該腳本喜歡上了同一個CSV(超過60萬行)的4倍。 使用完全相同的腳本,它會在不同的時刻停止... 停止之前完成的請求數:205 286 // 200 514 // 192 429 // 211 164 (我在每次嘗試之前截斷表)。 我總是使用相同的變量......如何使用內存可以增加? 它只是一個foreach循環......如果它的工作一次,它應該工作無限次,對吧?

謝謝,

Mickael。

PS:這裏是我的功能「INSERT_UPDATE」

function insert_update($row, $connect_id) 
{ 
    $table_name = "xxxxxxxx"; 
    $maxcol = 42; 

    $my_request = "INSERT INTO $table_name VALUES ('$row[0]'"; 
    $i = 1; 
    while ($i < $maxcol) 
    { 
     if (isset($row[$i])) 
      $my_request = $my_request.", '$row[$i]'"; 
     else 
      $my_request = $my_request.", ''"; 
     $i++; 
    } 
    $my_request = $my_request.")"; 
    if (mysqli_query($connect_id, $my_request) == FALSE) 
    { 
     echo "<p>$my_request</p>"; 
     exit(); 
    } 
} 
+1

你很容易受到[SQL注入攻擊(http://bobby-tables.com)。 'addslashes()'是完全沒用的垃圾,對保護你自己沒有用處。它是用絲網製成的避孕套 – 2014-10-09 14:35:18

+0

是每次都以相同順序回來的文件嗎?如果不是,那麼應該解釋爲什麼這兩個不同的停止....也許只是增加內存可用,並繼續:) ini_set('memory_limit','256M'); – myte 2014-10-09 14:37:03

+0

-MarcB好的但所有的CSV文件都是安全的。 -myte對於測試,我只是使用了一個csv,並且在每次測試後我都截斷了表格。其他任何關於如何在不同時刻停止的想法? 'memory_limit'被設置爲'-1'。 更重要的是,爲什麼它停下來的任何想法? – 2014-10-09 14:43:15

回答

0

你的函數不包含靜態和不應該留下任何痕跡。你的循環也不會在RAM中保留任何東西。因此,如果您沒有意外發現已使用的PHP函數中的任何memory_leaks,則另一個問題可能是垃圾回收器。這項服務不再使用內存。這個垃圾收集器不會在每個變量id被釋放後運行,而是在它自己的時間範圍內。

然而,你可以嘗試強制垃圾回收器來釋放內存。 (有人說,它不會影響內存說不上來。)

gc_collect_cycles() 

一些調試,還可以幫助您確定泄漏源:

memory_get_peak_usage(); 

您也可以嘗試增加該內存限制腳本。這個枯燥的工作可以在公共文件上完成,但它可能會佔用你所有的服務器內存。

ini_set('memory_limit', '1024M'); 

另一種選擇可能是嘗試不同的文件訪問方法和db連接,具體取決於您可用的方式。

如果一切都失敗了,創建一些類型的迭代。處理10個文件,然後使用偏移參數重定向到腳本,以便從上次停止的位置開始。重複,直到處理完所有文件。

http://php.net/manual/en/function.gc-collect-cycles.php

+0

謝謝你的幫助。事實是,當我檢查每次迭代使用的內存時,內存每次增加,我找不到原因。 – 2014-10-09 15:11:06

+0

在越來越多的線上測量內存,直到找到增加最多的線爲止。也許你至少可以嘗試其他邏輯。 – ToBe 2014-10-09 15:12:07

+0

是否沒有比其他人增加最多的特定線? – 2014-10-09 15:39:22