关于yii2框架中内存泄漏的解决方案
程序员文章站
2022-07-14 18:34:37
...
现象描述:
命令行执行一个7万行的脚本,循环里进行各种查询。结果每次都会报出内存溢出的错误,类似于这样:
第 475 次,消耗内存 312.68MB第 476 次,消耗内存 313.22MB第 477 次,消耗内存 313.79MB。还是报错。内存溢出。Allowed memory size of 402653184 bytes exhausted (tried to allocate 8388616 bytes) (手打日志记录)
经过分析,是不是存在没有及时销毁的变量,于是销毁了所有可能会影响性能的变量。然而发现内存还是不断上升。我很懵逼。
接着我就一段一段的进行调试,
foreach ($query->batch(100, Yii::$app->slave_db_ss) as $items)
{
//100数据循环中...
$upt_data = [];
foreach ($items as $item){
... //中间代码全部注释
}
}
这样注释了之后发现,很快就执行完了十几万数据。于是还是一段一段的在循环里注释。这里可以发现yii框架自带的这种循环大数据还是蛮好用的。
一直查,最终问题定位在一个这样的问题里:
$tb = 'userinfo';
$sql = "select login_num from " . $tb . " where uid = '" . $item['pf_uid'] . "'";
$login_info = Yii::$app->slave_db_passport->createCommand($sql)->queryOne();
循环里只保留这段代码。执行脚本发现内存还是不断上升,cpu占到了50%。
于是跑过去问我们老大,人家毕竟历经沙场。很快他看完我的代码,也定位到了这里。于是他假设说是不是yii2框架这里不会自己释放内存呢?然后我就下去google了下。果然,高人多。
这里放上链接:
http://www.yiichina.com/tutorial/1397 这个里面写的还是研究的比较深入的。
接下来就好办了。将这里的查询换成原始的连接试试。果然,内存上升的非常慢了,可以说这才是正常现象。现在的内存也就是50m左右,cpu也稳定在7%左右。
代码优化后,再跑脚本,1分钟左右吧,脚本就跑完了。重点是不会再报出内存错误了。所以,以后考虑问题还是要深入。敢于质疑。以后如果遇到这种内存错误,一定要先检查自己的代码是不是有内存泄漏的地方。不要想着先设置php的内存。这样只会治标不治本。
以上就是我研究两天的结果。功夫不负有心人啊,加班值了。
上一篇: 什么情况下会导致内存泄露