【问题标题】:Avoid fatal error memory exhausted before it happens避免致命错误内存在它发生之前耗尽
【发布时间】:2017-07-31 07:54:27
【问题描述】:

我试图通过在实际发生之前确定它是否会发生来避免内存耗尽的致命错误。尽管我的 PHP 安装的内存限制为 128M,但允许的大小为 134217728 字节;我猜 PHP 在这里提供了一些空间来解释额外的字节。无论如何,我试图读取的实际文件大小是 134171737,小于 134217728。但是 PHP 说它试图分配 134179929。

这些数字似乎是任意的。如果(通过比较即mem_size > file_size)这些数字实际上并不准确,我如何检查将文件读取到变量是否会耗尽内存?

致命错误:第 159 行 C:\xampp\htdocs\backup\vendor\cake\File.php 中允许的内存大小为 134217728 字节已用尽(尝试分配 134179929 字节)

注意:我知道我可以发送readfile。我只是很好奇在这种情况下如何避免这样的错误。

【问题讨论】:

  • 不知道你在问什么
  • 如果我将文件读取到变量并回显该变量,并且如果文件大小大于内存限制,我可以在回显变量之前检查它,从而避免内存耗尽错误。但是由于文件大小似乎不能确定分配的内存,所以我卡住了。
  • 您似乎已经知道答案 - 首先使用 filesize() 检查文件大小,确保为运行时/代码的其他部分需要的内存留出适当的填充...跨度>
  • 正是我的观点:如何确定适当的填充?因此,为什么我说这些数字似乎是武断的。因为我已经读过 file_get_contents 使用了某种输出缓冲区,我认为这会导致额外的字节数,但我似乎找不到任何关于如何确定这些额外字节对于文件 n 大小的大小的文档。 .
  • 你必须首先将整个文件读入内存吗?

标签: php error-handling out-of-memory


【解决方案1】:

您永远不应该尝试将总可用内存分配给您的运行时 - 您的语言级别越高,这一点就越真实。

即使使用非常低级的语言(PHP 当然不是),您不仅需要用于分配字节的内存(将进入堆空间),还需要用于指令和调用堆栈。

随着您进入更高级别的解释语言,这种开销只会增加 - 解释器将需要自己的内存量,并且可能没有任何好的或可靠的方法(无论是跨版本还是跨配置相同版本或相同配置中的执行)来确定环境/运行时需要多少“填充”。

在你的情况下,你已经怀疑你可能会接近 - 你应该选择一个“安全”数量的缓冲区空间留给运行时,例如,如果你知道你将尝试分配超过 90您不应该占用运行时可用内存的百分比(对于像 PHP 这样的语言,您很可能在其他消费者竞争相同资源的服务器环境中运行,该阈值可能会低得多)。

一般来说,最好避免消耗过多的内存,尤其是在解释型和基于 Web 的环境中。虽然为了缩短执行时间而进行内存权衡可能是值得的(特别是当在内存中加载更多数据时,可以节省大量重复计算的时间,这些重复计算将花费更长的时间来重复分配内存,然后重新分配内存以重新分配它),您在这里谈论的案例对此没有任何意义。这就是您更喜欢流式模型的原因,在这种模型中,您只分配必要的内存来读取您可以合理服务的文件部分(而不是您必须重复处理该文件的不同部分的情况) ,然后根据您刚刚处理的内容重新处理其中的某些部分 - 例如,必须在文件中频繁回溯才能知道下一步该做什么的例程。

【讨论】:

    猜你喜欢
    • 2015-07-02
    • 2011-07-12
    • 2010-12-15
    • 1970-01-01
    • 2014-02-26
    • 2017-12-13
    • 2012-04-20
    • 2017-06-21
    • 1970-01-01
    相关资源
    最近更新 更多