php - 改进 PHP 导入脚本的内存使用

标签 php memory memory-management

我有一个导入 CSV 文件并经历数万次迭代的 PHP 脚本。随着脚本运行数小时,内存使用量不断增加,如果文件足够大,脚本会耗尽大量内存,以至于整个机器都停止运行。

现在我使用的唯一技术是在完成后尽我所能unset()。我试图隔离使用最多内存的部分,但似乎我脚本中的每个函数都只是压在 Camel 背上的一根稻草,并且使用“尽可能少的内存”。

那我该怎么办呢?

我尝试研究基准测试/分析工具,但没有找到任何好的东西。我在 Windows 机器上,通过 SSH 连接到 Linux 机器。

最佳答案

好吧,既然你在寻找技术,那我就列举一些...

<强>1。不要读取文件,流式传输它们

与其调用 $data = file_get_contents($file),不如使用 fopen 打开它,并且只读取您在那个时间点需要的数据(fgets fgetcsv 等)。它会稍微慢一点,但会使用更少的内存。

<强>2。升级到 5.3.4

如果您仍在使用 PHP 5.2.x,升级到 5.3.x(最新的 5.3.4)将大大节省内存。它包括一个垃圾收集器,可以在一段时间后清理释放的内存。

<强>3。不要在全局范围内使用任何东西

不要在全局范围内存储任何信息。它直到执行结束才被清理,因此它本身可能是内存泄漏。

<强>4。不要传递引用

PHP 使用右复制。传递引用只会增加 unset 无法获取所有引用的可能性(因为您忘记了 unset 其中一个引用)。相反,只需传递实际变量。

<强>5。剖析代码

分析您的代码。在每个函数调用的开始和结束处添加调试钩子(Hook),然后记录它们在每个函数的入口和导出处观察内存使用情况。比较这些,您就会知道每个函数使用了多少内存。找出最大的违规者(那些被调用很多,或使用大量内存的)并清理它们......(最容易挂的果子)。

6.使用不同的语言

虽然您可以使用 PHP 来完成这项工作(我经常这样做),但要意识到它可能不是完成这项工作的最佳工具。其他语言正是为这个问题而设计的,所以为什么不使用其中的一种(例如 Python 或 Perl)...

7.使用临时文件

如果您需要跟踪大量数据,请不要一直将它们全部存储在内存中。创建暂存文件(临时文件)以在您未明确使用数据时存储数据。仅在您要使用该特定数据时加载文件,然后重新保存并删除变量。

<强>8。仅限极端情况:不要使用大型数组!

如果您需要跟踪大量整数(或其他简单数据类型),请不要将它们存储在数组中! zval(内部数据结构)有相当多的开销。相反,如果您真的需要存储大量整数(数十万或数百万),请使用字符串。对于 1 字节的 int,ord($numbers[$n]) 将获取 $n 索引的值,并且 $numbers[$n] = chr($value); 将设置它。对于多字节整数,您需要执行 $n * $b 以获得序列的开始,其中 $b 是字节数。我强调,这应该只在需要存储大量数据的极端情况下使用。实际上,临时文件或实际数据库(可能是临时表)会更好地提供服务,因此这可能不是一个好主意...

祝你好运......

关于php - 改进 PHP 导入脚本的内存使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4465086/

相关文章:

c - C 中变量和内存概念的重用

c - 地址加 `int`导致int加4次

java.lang.OutOfMemoryError : PermGen space in play framework

Java内存优化(如何避免内存泄漏 - 具体示例)

php - 编辑表值代码不起作用

javascript - TinyMCE:如何在上传图片时保留相对 URL 但在使用 "insert link"选项时使用绝对 URL?

php - SQLSTATE[HY093] : Invalid parameter number: parameter was not defined : PHP PDO Object

ios - Xcode 自动化 UI 测试日志内存使用

php - 使用 Laravel Auth 伪造登录

debugging - 什么可以在 Linux 中执行类似 Cheat-Engine 的任务?