【问题标题】:Weird memory allocation error奇怪的内存分配错误
【发布时间】:2018-05-26 13:33:12
【问题描述】:

我遇到了臭名昭著的内存分配错误。
所以,我有以下代码:

/** @var \Illuminate\Database\Eloquent\Collection|MPL[] $mpls */
foreach ($mpls as $index => $mpl) {
    $mplMIDs = [];
    $mpl->getMIDs(false, false)->each(function(MID $mid) use (&$mplMIDs) {
        if ($mid->isSingleLinked()) {
            $mplMIDs[] = $mid->mid_key;
        }
    });

    if (!$mplMIDs) {
        // most of the times the code enters here
        unset($mpls[$index]);
    }
    gc_collect_cycles() // working only if this adds this row
}

如你所见,我有。 $mpls 数组,对于每个 $mpl,我从数据库中获取它的 MIDsgetMIDs 函数),然后对于每个 MID,我检查它是否是我所说的 singleLinked(也调用数据库)。 关键是我有一个对象数组,我向它们插入更多对象,并向这些对象插入更多对象:

$mpls (array of objects) [
   $mpl (object) {
       $mids (array of objects) {
            $entities (array of objects)
       }
   }
   ... more $mpls... 
] 

由于某种原因,内存很快就满了(大约 20 秒内 1GB!)我认为 unset 应该可以修复它,但只有当我通过 gc_collect_cycles 强制垃圾收集时才有帮助 可能是因为对象“深”而发生这种情况?

PHP 版本:PHP 5.6.30
我得到的错误:

PHP Fatal error:  Allowed memory size of 1073741824 bytes exhausted (tried to allocate 72 bytes) in /larvael/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 303

【问题讨论】:

  • 实际问题是什么?分配的内存增长了,所以...?
  • 对象有多大?制作一个对象的 var_dump,如果结果站点太大,请考虑将您可以静态的内容设为静态,这会降低内存量,并且在某些情况下会大量使用实例。
  • @zerkms 它崩溃了,也许如果整个数据超过 1GB,为什么每次迭代都不干净,因为unset
  • @MarceloStaudt 对象很大,但不超过 10 MB(永远..),感谢静态想法,但我不明白为什么每次迭代都没有清理它们!吓死我了!
  • @Michael 详细说明“崩溃”。是被OOM杀手杀死的吗?还是段错误?或者究竟是什么?

标签: php


【解决方案1】:

php.ini 文件 如果找不到 php.ini 文件或无权访问它,请打开引发错误的文件 ini_set("memory_limit","16M");

【讨论】:

  • 为什么这是一个解决方案?他的内存限制目前约为1GB,减少它会导致错误更早发生......
  • 为您的 php.in 文件创建内存限制
猜你喜欢
  • 2014-07-28
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多