我需要处理一些大文件,比如每个文件50 to。我发现PHP函数消耗了大量内存。在下面的示例中,PHP函数使用的内存最终是文件大小的4 (4)倍。我可以理解文件内存大小的两倍,但不是四次的短暂使用。最后,PHP会击穿memory_limit。虽然我可以增加PHP,但这不是一个好的长期解决方案,因为我可能需要处理更大的文件,而且在生产环境中,让memory_limit占用每个进程400 up是不可取的。
代码:
$buf = '';
report_memory(__LINE__);
$buf = file_get_contents('./20MB.pdf');
report_memory(__LINE__);
base64_encode($buf);
report_memory(__LINE__);
urlencode($buf);
report_memory(__LINE__);
function report_memory($line=0) {
echo 'Line: ' . str_pad($line,3) . ' ';
echo 'Mem: ' . str_pad(intval(memory_get_usage()/1024 ) . 'K',8) . ' ';
echo 'Peak: ' . str_pad(intval(memory_get_peak_usage()/1024) . 'K',8) . ' ';
echo "\n";
}
输出:
Line: 4 Mem: 622K Peak: 627K
Line: 7 Mem: 21056K Peak: 21074K
Line: 10 Mem: 21056K Peak: 48302K
Line: 13 Mem: 21056K Peak: 82358K
可以看到,对于一个20 to的文件,当前内存使用率徘徊在21 to,而峰值内存使用量则跃升到疯狂的82 to。
本例中使用的PHP函数是任意的,我可以轻松地在str_replace、is_string、gettype等中进行交换,得到相同的结果。
问题是我如何阻止PHP这样做?
环境是CentOS 6.6,运行一个库存PHP5.3.3。
谢谢你的见解。
发布于 2015-03-16 07:03:04
你在做密码。考虑到您的PDF基本上是“随机”二进制垃圾,那么中的许多字节的是不可打印的。这意味着您将从一个字节的“二进制”字符转到3+字节URL编码的字符串。如果你有一个20 memory,那就不足为奇了,把里面的文本数量增加三倍会使你的记忆膨胀。请记住,PHP在运行时必须保留PDF的两个副本:原始“原始”版本和正在对其进行的任何转换的工作副本。
假设“每个字符都被编码”,则20 meg将转换为一个60 meg编码的字符串,从而导致20+60 = 80 meg峰值使用,即使60 meg编码版本立即被丢弃。
https://stackoverflow.com/questions/29079902
复制相似问题