我的 php 脚本停止运行,因为内存不足。 这是我的代码:
$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(超过 600k 行)上运行了 4 次脚本。 使用完全相同的脚本,它会在不同的时刻停止...... 停止前完成的请求数:205 286//200 514//192 429//211 164 (我在每次尝试之前截断表格)。 我总是使用相同的变量...使用的内存如何增加? 它只是一个 foreach 循环...如果它工作一次,它应该工作无限次,对吗?
谢谢,
迈克尔。
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();
}
}
最佳答案
您的函数不包含静态数据,并且不应留下任何内容。您的循环也不在 RAM 中保留任何内容。所以,如果你没有意外发现所使用的 PHP 函数中存在任何内存泄漏, 另一个问题可能是垃圾收集器。此服务释放不再使用的内存。这个垃圾收集器不会在每个变量 id 释放后运行,而是在它自己的时间范围内运行。
但是,您现在可以尝试强制垃圾收集器释放内存。 (有人说不会影响内存,不知道)
gc_collect_cycles()
一些调试还可以帮助您识别泄漏的来源:
memory_get_peak_usage();
您还可以尝试增加此脚本的内存限制。然而,这不应该在公共(public)可用文件上完成,因为它可能会快速占用您所有的服务器内存。
ini_set('memory_limit', '1024M');
另一个选择可能是尝试不同的文件访问和数据库连接方法,具体取决于您可用的方法。
如果所有其他方法都失败,请创建某种迭代。处理 10 个文件,然后使用偏移参数重定向到您的脚本,从上次停止的位置开始。重复此操作,直到处理完所有文件。
关于php mysql 循环内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26281107/