【问题标题】:PHP Memory exhausted - array or sql?PHP内存耗尽 - 数组或sql?
【发布时间】:2012-02-12 13:04:58
【问题描述】:

我有一个要在循环中追加的数组:

array_push($obj->{$type.'listings'}, $listing);

循环进行了一系列远程调用,并提取了我想要存储在文件中并用作某种缓存的数据。

在运行这个“缓存例程”时,如果我序列化这个数组,它报告说它刚刚超过 5MB。要创建 5MB 数组,脚本会耗尽 100MB 内存。我非常小心地取消设置变量以释放内存。我已经将所有内容都注释掉了,并通过未注释的函数来查看内存在哪里。当我推送到阵列时,它肯定会发生。如果我不使用 array_push,然后使用 memory_get_usage() 和 gc_collect_cycles(),我可以看到相当稳定的内存使用量和一些峰值,但它会在移动时释放自己。

只要我推送到数组,它就会变得很疯狂,内存使用量就会堆积起来。

对于如何处理这种情况有什么想法吗?

我不能用 PHP 构建这样的大型数组吗?

有没有办法在我构建时将数组刷新到文件中?并假设我可以将其构建并存储在文件中。当我想使用它时,我会在从文件中提取后使用相同数量的资源......还是内存耗尽只是因为它在构建时被动态添加?

这是我应该考虑使用 SQL 的事情吗?并将循环的每次运行存储在单独的行中?

只是为了好玩,我添加了:ini_set('memory_limit', '-1'); 只是为了看看它是否会运行。

确实如此,内存使用量达到了 100 MB 以上的峰值,序列化对象大小刚刚超过 8 MB。现在,这并没有什么帮助,因为我只是在处理一个数据样本,而且这可能会变得更大。

无论如何,您对优化这种情况的任何想法都会很棒。

【问题讨论】:

  • 你说你对取消设置很小心——你是在释放你的 mySQL 结果吗?如果你做得足够多,这也会吸走内存。
  • 我现在没有在 SQL 中存储任何东西。我只是问那是否是一条更好的路线。但是在获取数据时有一些 sql 查询,为了释放它们,我使用 unset($result) 其中 $result 保存结果集
  • 我从没这么说过。我的意思是使用 mySQLi_Result::Free() 之类的东西或您使用的任何东西 - 不确定 unset() 是否会完全释放您请求中的内存。

标签: php sql memory


【解决方案1】:

对于 5MB 的数组,PHP 肯定不会使用 100MB。

在脚本中使用http://it.php.net/memory_get_usage 来查看它的增长点

考虑我在 PHP 数组中构建数百万(200 万)个条目而没有问题。 (内存使用小于 200MB)

【讨论】:

  • 是的,好吧,这就是我认为的 5MB 序列化对象不占用 100MB 内存。我一直在使用 memory_get_usage 来尝试解决这个问题,它似乎随着我添加到数组中而增长。对此感到困惑。
  • 自动换行的地方很不靠谱
  • 是的,有一个按钮可以切换换行。
  • 我不知道问题出在哪里。它仍然会消耗大量构建数组的内存。我只是对内存设置了“无限制”,它似乎有效。当我开始获取更大的数据时,我们将看看会发生什么。
【解决方案2】:

我发现,如果您使用 foreach 循环遍历列表,如下所示:

foreach($list AS $value)
{
   $list[] = trim($item);
}

您可以无限增加$list 的大小,从而导致无限或接近无限的循环。当带有循环的脚本消耗更多内存时,通常是由于循环构建的列表太大而内存无法处理。

【讨论】:

    【解决方案3】:

    使用包含几兆字节数据的序列化数组作为“某种缓存”显然是个坏主意。

    【讨论】:

    • 缓存大数组并没有什么问题:它甚至可以大大提升性能。
    • 谢谢罗宾。想要缓存数据的主要原因是不必在每次加载页面时都执行所有远程过程。所以通过在本地缓存数据......好吧,这是必要的
    • @RobinUS2 哦,当然没有错。除了消耗大量内存和解析:)
    • @SenicaGonzalez 提出问题,必须仔细阅读答案。没有人说你不应该使用缓存。这是你选择的方式显然是错误的。你能看出区别吗?
    • @Col。 PHP 中的 Shrapnel Unserializing 确实会在 PHP 中使用内存导致一些开销,但是它非常快。整个序列化过程中最慢的部分是 serialize() 本身。 Zend 等框架为其缓存前端启用自动序列化的主要原因之一。
    猜你喜欢
    • 2015-10-01
    • 2014-09-08
    • 1970-01-01
    • 2013-07-06
    • 2014-06-28
    • 2011-04-20
    • 1970-01-01
    • 2013-07-22
    相关资源
    最近更新 更多