Allowed memory size of 134217728 bytes 错误解决心得
错误如下:
FatalErrorException in String.php line 575:
Allowed memory size of 134217728 bytes
服务器 :linux + nginx + php-fpm
报的错误很简单,php.ini
中默认内存限制是128M,改大?方案不可取,按照我java程序员跑来写php的野路子来说,肯定我的代码出问题了。
网上查了查有人说
unset($var)
,没有释放变量,内存没有释放,越用越高。 有道理!
$tyusers = User::orderBy(isset($data['sort'])?$data['sort']:"uid",isset($data['order'])?$data['order']:"asc")
->where(function($query) use($data) {
$query->where('subscribe',1);
if(isset($data['issteam'])){
if($data['issteam'] == 0 ){
$query->whereNull('steamid');
}else if($data['issteam'] == 1){
$query->whereNotNull('steamid');
}
}
})
->offset(($page - 1) * $rows)->limit($page * $rows)->get();
$cellData = [];
array_push($cellData,array("ID","邮箱","SteamID","注册时间","昵称"));
foreach ($tyusers as $tyuser){
array_push($cellData,array($tyuser->uid,$tyuser->email,$tyuser->steamid." ",$tyuser->created_at,$tyuser->name));
}
Excel::create(date("Y-m-d-His").'-用户列表'.(($page - 1) * $rows).'到'.($page * $rows),function($excel) use ($cellData){
$excel->sheet('score', function($sheet) use ($cellData){
$sheet->rows($cellData);
});
})->export('xls');
// 释放对象
unset($tyusers);
unset($cellData);
于是乎我高高兴兴的加上后面两句,so easy。然后发现还是不行!!!还是报错!!!
joy: :joy: :joy:
仔细一想,php作为世界上最美丽的语言不会因为我没有主动unset($var)
就撑爆内存吧,即使我没有及时unset($var)
,我相信当此次访问结束时他也会被回收。(对于php的内存机制不是很了解,但我依然这样相信。)
后来经过仔细观察,10000行一页,我导出第一页没问题,只有第二页有问题,想了想上面是字符串类报错。最后定位问题,查询的结果集太大,之前user表里面只有七八个字段,后来整合论坛,直接又加进来不下二十个字段,所有字段都查询出来肯定撑爆内存。
最后修改代码:
$*****->get(["uid","loginid","steamid","created_at","name"]);
总结:用什么就拿什么,不用就别浪费资源,培养良好的代码习惯。
triumph: :triumph: :triumph:
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由 Summer
于 7年前 加精
查询出需要的字段,这是明智的选择。mysql 优化就要避免
select *
的情况确实应该养成好习惯啊! 该严谨的地方还是得严谨
也可以使用,
ini_set ()
,但用什么取什么要更好点可以试试分次导出
用
$query->each(Closure)
也能解决这个问题,each 默认每次拉取 1000 条下次数据量大的时候还是一样会撑爆
@ouminghai 最多导出10000条,这种操作,没有界限就没有尽头。
@zhwei 可以试试
@KubiLi 是的,之前我就是每次导出最多5000条,不然像php这种不限制内存,能把服务器内存吃完。
试试手动GC