文章目录
在跑审计前250名用户清单数据时,总是因为内存占用过大而异常退出。查看代码,也就是两个循环嵌套连接MySQL查询数据然后处理显示出来(不会存在一次取出数据超内存的情况),具体循环代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| for($i = 0; $i < $total_count['total_count']; $i += $count){ echo "mem".memory_get_usage()."\n"; $items = $this->Model_data_table_payurl->get_all_order_by_user_id($big_app_id, $first_second, $last_second, $v['user_id'], $i, $count); echo "mem".memory_get_usage()."\n"; foreach($items as $key => $row) { $audit_cfg = MY_Audit::get_audit_sub_app_cfg($big_app_id, $row['trade_type']); MY_Time::set_timezone($big_app_id); $date = date("Y-m-d H:i:s",$row['createtime']); $ips = $this->get_ips_by_day($big_app_id, $row['zoneid'], $date, $row['userid']); echo $game_desc."\t".$audit_cfg['partner']."\t".$app_ret['appname']."\t".$audit_cfg['desc']."\t".$audit_cfg['sales_mode']."\t".$audit_cfg['country']."\t".$audit_cfg['shore']."\t". $date."\t".$row['curType']."\t".$row['userid']."\t".$row['zoneid']."\t".$row['name']."\t".$row['num']."\t".$row['cost']."\t".$row['ip']."\t".$ips."\n"; unset($items[$key]); } }
|
其中echo "mem".memory_get_usage()."\n";
显示查询数据库之前与之后的内存占用情况,发现内存是一直递增的,信息显示如下:
1 2 3 4 5 6 7 8
| mem5933840 mem9584368 mem10304976 mem12652816 mem12918072 mem14033464 mem14451576 mem16399352
|
调查及解决的过程:
该函数将会释放当前查询所占用的内存并删除其关联的资源标识。通常来说,PHP 将会脚本执行结束后自动释放内存。如果当前执行的请求将要花很长时间并且占用比较大的资源时,该函数可以在一定程度上降低资源的消耗:
1 2 3 4 5 6 7 8 9 10
| $query = $this->db->query('SELECT title FROM my_table'); foreach ($query->result() as $row){ echo $row->title; } $query->free_result();
$query2 = $this->db->query('SELECT name FROM some_table'); $row = $query2->row(); echo $row->name; $query2->free_result();
|
于是利用此方法来释放资源,但最终发现每次调用完只释放了几K的内存,犹如杯水车薪并不能解决内存持续递增的问题
- 在打印$db对象时(如何打印看这里)发现其中一项[save_queries] => 1,所以打开system/database/DB_driver.php查看CI源码,看到:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| var $save_queries = TRUE;
if ($this->save_queries == TRUE) { $this->queries[] = $sql; }
$time_start = list($sm, $ss) = explode(' ', microtime());
if (FALSE === ($this->result_id = $this->simple_query($sql))) { if ($this->save_queries == TRUE) { $this->query_times[] = 0; }
$this->_trans_status = FALSE;
if ($this->db_debug) { ...
|
- CI db会将所有的查询sql和和sql执行时间保存下来,为了debug。
所以到这里问题已很明显,我就将$save_queries的值改为FALSE,然后重新执行,结果如下:
1 2 3 4 5 6 7 8
| mem5924328 mem9573632 mem5971680 mem8307064 mem5971504 mem7091896 mem5971528 mem7916000
|
之前的内存递增已解决。
当你执行大数据时,记得$save_queries = FALSE;
或在model中加入 $this->db->save_queries = FALSE;