【问题标题】:PHPExcel not releasing memoryPHPExcel不释放内存
【发布时间】:2018-01-26 10:58:31
【问题描述】:

我有一个脚本可以读取附有 Excel 文件的电子邮件。
我正在使用 PHPExcel 来解析这些文件。

我目前遇到的问题是一封附有五个电子表格的电子邮件。
每次加载第五个文件时,PHP 都会耗尽内存。

最初我尝试在每次完成后都取消 ($objPHPExcel = NULL;) 和取消设置 (unset($objPHPExcel);) PHPExcel 对象 它。那没有帮助。

然后我尝试将垃圾收集添加到进程 (gc_enable(); $cycles_collected = gc_collect_cycles();)。那没有帮助。

我将当前的 php 内存使用量打印到我的错误日志中,我可以看到它随着将每个 Excel 文件加载到 PHPExcel 中而增长,我还可以看到内存使用量并没有随着每个NULL、unset 而减少或gc_collect。

以下是在 PHP 内存不足之前和之后输出到我的 error_log 的一些示例:

[17-Aug-2017 16:04:29 America/Chicago] [Blackouts] Current Memory Usage at beginning of script before loading Excel file: 85575176

[17-Aug-2017 16:04:32 America/Chicago] [Blackouts] Current Memory Usage after loading Excel file: 104474632

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] Current Memory Usage after parsing of Excel file is complete: 104480416

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] Current Memory Usage after PHPExcel object set to null: 104480536

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] Current Memory Usage after PHPExcel object is unset: 104480256

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] gc collected cycles: 0

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] Current Memory Usage after gc_collect_cycles: 104480416

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] script completed: /path/to/file/Schedule Week of 14 Aug 2017 - 21 Aug 2017.xlsx

[17-Aug-2017 16:04:34 America/Chicago] [Blackouts] Current Memory Usage at beginning of script before loading Excel file: 104484072

[17-Aug-2017 16:04:36 America/Chicago] [Blackouts] Current Memory Usage after loading Excel file: 122069128

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] Current Memory Usage after parsing of Excel file is complete: 122114480

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] Current Memory Usage after PHPExcel object set to null: 122114600

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] Current Memory Usage after PHPExcel object is unset: 122114320

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] gc collected cycles: 0

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] Current Memory Usage after gc_collect_cycles: 122114480

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] script completed: /path/to/file/Schedules Week of 14 Aug 2017 - 21 Aug 2017.xlsx

[17-Aug-2017 16:04:38 America/Chicago] [Blackouts] Current Memory Usage at beginning of script before loading Excel file: 122118192

[17-Aug-2017 16:04:39 America/Chicago] PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted at Zend/zend_vm_execute.h:22207 (tried to allocate 72 bytes) in /mnt/nas_001_www/Classes/PHPExcel/Cell.php on line 551

【问题讨论】:

  • 最后一张纸有多大?喜欢行和列
  • 我曾经使用 phpExcel 重构过一个项目。在增加内存并使用功能强大的服务器后,生成 excel(5k+ 行)仍然需要很长时间。我最终优化了我的数据获取并切换到使用 sep=; 生成一个 csv。元数据标签,以便它可以用 excel 打开。
  • 所有的纸张大小都差不多。最后一张纸是 9 列和大约 1500 行。
  • @Rienk,我很想将其转换为 csv,但不幸的是,我需要能够读取单元格颜色,因为它们向每个单元格传达了某些含义。
  • 发布脚本。你一定是做错了什么。

标签: php memory phpexcel


【解决方案1】:

您不能简单地取消或取消设置 PHPExcel 对象以将其从内存中删除,as explained in the documentation,因为它包含循环引用(工作簿包含工作表对象的集合,并且每个工作表都引用工作簿;与工作表和单元格类似对象)不能简单地通过未设置来解决。相反,您需要先打破这些引用

$objPHPExcel->disconnectWorksheets();
unset($objPHPExcel)

【讨论】:

  • 感谢@Mark Ba​​ker 的帮助。但是为什么不在 PHPExcel 类的析构函数中包含 disconnectWorksheets() 函数,这样开发人员就不必显式调用它呢?我确信这是有充分理由的,或者只是我对类的功能缺乏了解。再次感谢!
  • 理论上是可以的,尽管有几种情况需要独立调用;但我记得 x 年前写的时候,它在析构函数中调用时不起作用....我的回忆是它与工作簿中链下析构函数的执行时间/顺序有关到工作表到单元格集合到单元格
  • 很公平。再次感谢马克!
  • 我想对这个答案表示非常感谢。我定期对一个包含 100-120 个电子表格的目录运行 PhpSpreadsheet,我的内存使用量从 2GB 下降到 100MB!
猜你喜欢
  • 2016-03-13
  • 2017-06-29
  • 2011-06-30
  • 2016-09-14
  • 2015-08-19
  • 2012-05-15
  • 2011-09-30
  • 2012-03-18
  • 2011-08-10
相关资源
最近更新 更多