php内存泄漏的后果,记一次php内存泄漏的排查经过

实际问题

在一个项目里,需要后台运行一个php文件,这个php主要功能就是在一个永远为真的循环里,分别从Redis以及Memcache中拉取数据,然后在php中正则匹配后,把数据推回Redis。

在开发环境是没有问题的,但是上线后却发现运行了几分钟后,进程就没有异常报错的退出了,没有触发任何错误日志,让我一脸懵逼(黑人问号脸)

问题分析

确定问题首先在每次循环里加入计数器,并且使用memory_get_usage()对每次循环的内存量进行记录。

发现程序每次循环次数到24500+就自动退出了,同时内存量也是一路高歌最后涨到127.3M左右就停了。

去到php.ini查找max_memory_limit发现正好是128M。

由此确认,这个文件的异常退出就是由于运行时内存泄漏导致内存消耗量超过php配置文件上限被退出了。

定位问题

通过memory_get_usage()以及用continue;截断代码来不断缩减范围,配合使用来定位内存泄漏具体代码。

1

2

3

4

5

6

7

8function print_max_memory(){

static $max_memory = 0;

$memory = memory_get_usage();

if($max_memory < $memory){

$max_memory = $memory;

cli_log(sprintf("max_memory : %s", $max_memory));

}

}

问题总结

AnalyzeProcess.php在进程运行时,每一次while循环都发生了内存泄漏,泄漏量在7~8Kb,最后循环次数到达24500+时,达到php配置文件的内存上限128m,被强制退出。

解决问题

- 问题1

起因

使用list函数时,多定义了一个NULL的下标。

list($game, $server, $username, $role, $ip, $content,$tid) = $data;

实际上$data只有[0]-[5]一共6个下标,$tid为第7个NULL的下标,循环运行时出现内存泄漏。

解决方案

去掉这个多余的下标。

- 问题2

起因

foreach时调用了一个空的数组去做preg_match

解决方案

在preg_match匹配前做一个if判断,若为空则跳过该次循环

- 问题3

起因

用if判断了一个数组不存在的下标

解决方案

把该判断放回到正确的循环语句中

问题总结

解决这个问题后,回望代码,其实出现的问题都是因为代码不够健壮,run一次可能问题不大,但是一直while的run就发生内存泄漏问题了。故需要在码代码的时候注意一些细节的位置,让程序能够平稳运行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值