来看这段程序:
我们想让程序将所有数组中出现的文件聚合成一个文件,保存成immm7.sql。
在命令行下运行的结果如下图所示:
大致意思是说内存溢出了。
我们来分析一下这种情况产生的原因:
首先查看一下php.ini中memory_limit的设置值,检查之后发现是128M。
再来看数组中指定的几个sql文件的大小:
可以看到第一个文件和最后一个文件稍微小一点(一个30多兆一个1兆多),其余三个都是60多兆。5个文件的大小没有一个超出128M。怎么还会有内存溢出呢?
继续分析之前的那段程序,问题就出在这里:
foreach ($sqlFiles as $v) {
$str = file_get_contents($v);
fwrite($handle, $str);
}
我们看到,第一次file_get_contents函数将文件内容读取到内存,紧接着第二次file_get_contents函数继续将下一个文件的内容读取到内存,两次读取之间内存是会有"叠加效应"的。即在第二次file_get_contents函数未完全读取完文件之前,前一次读取时占据的内存不会被释放。只有当第二次函数读取完文件之后,前一次占据的内存才会释放。我们看到由于有几个文件的大小都是60多兆。很明显叠加之后超出了128兆。
解决办法很简单,写入文件之后我们可以手动释放内存:
foreach ($sqlFiles as $v) {
$str = file_get_contents($v);
fwrite($handle, $str);
$str = '';
}
但是这样,仍然不能避免读取大文件时,内存超出128M的可能。因此我们想到可以通过调整memory_limit的值来避免这种错误的产生(使用ini_set()函数临时设置这个值即可),或者我们也可以从程序端去做控制,下面的方法就可以很好地解决这个问题: