【发布时间】: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,我从数据库中获取它的 MIDs(getMIDs 函数),然后对于每个 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