2014-10-09 55 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