现在线上是用的Gateway,分布式架构,Register,Connect,Worker都分开容器部署,现在有个很奇怪的现象,关于worker进程的容器主机内存会一直持续增长,连续跑3天 内存使用多占了2个G,但是系统监控和atop查看到 整个php的worker进程一直都是在 300-400M左右,总之都不会超过1G,但是我一旦重启worker进程之后立马可用内存多出来2个G。。。。。,完全找不到头绪,进程内存占用比较少,没有看到明显增长,但是一旦重启进程缺能释放很多内存空间出来
求大佬分析一下可能的原因
walkor大大关于内存泄漏的可能原因写的很详细,据此自查:
https://wenda.workerman.net/question/3307
是这样的,我进程里面确实有一些静态数组数据,但是监控显示所有的PHP进程累计到400多M的的时候不再增加了,也趋于相对稳定,但是宿主机内存一直在缓慢增加,当我重启或者关闭PHP进程容器的时候,立马会腾出2个G,我所有PHP进程加起来也没2个G内存占用啊
看一下你的业务代码,这么多内存肯定是业务代码有问题
@3938:
1、既然有静态数组,那么要注意必要条件下的及时释放,否则就会有内存泄漏,所以你这情况十有八九就是这个造成的,具体还得你自己排查确认;
2、PHP进程累计到400多M不再增加? 这个400是看的top的哪个指标? 另外什么又是宿主机内存?
3、至于重启进程,那肯定会腾出空间,因为旧的进程已经退出了,进程所占用的内存会得到释放,这个不难理解。
atop所有php进程累计的RSIZE,我上面说 400M -> 2G 这个关键点是忽略了吗?为什么所有PHP进程总共统计400M ,释放后会腾出2G?静态数组是固定的SET,没有累加操作,而且只有那么几个点,启动时 每个BK进程12M,最后会到20M,容器或虚拟机部署的主机就叫宿主机啊
我疏忽了你提及的容器二字;根据php进程报告截图来看,只能看到负载略高,那应该是Rabbit那几个进程wait造成的阻塞引起的,busy也能说明这一点,不过看不出来是否这组进程里有使用定时器,这个上面链接里也有详细的注意事项说明;然后没用过atop; 另外对于top或htop监控参数而言,如果特定容器内所有PHP进程对应的RES字段(应该类似于atop的rsize吧)如果在足够长的周期内一直维持在300~400M左右,那理论上说明不存在内存泄漏的问题;至于2G宿主机内存的释放是不是重启worker进程容器后就判定一定是worker进程在吃内存,这个难说需要你自己多个时间点检测排查环境,毕竟中间有层容器,容器本身以及容器内的其他服务进程对资源的消耗情况也不可忽略;建议你尝试限制下worker进程所在的docker容器内存上限,然后这样便于集中观测是不是worker进程在吃内存,当然了业务代码层面还是需要再查查的,综合排查吧。
贴一张status,BK进程是核心的业务进程,里面就有我所说的静态数组作为数据缓存点,这些数组都是直接set不存在一直累加
剩下的rabbit那个是消息队列处理一些异步任务,内部没有静态变量,阻塞的原因rabbit需要wait判断新的消息
这样的容器还有好几个,整体400M是包括了其他的这样的worker业务容器还有connect容器
现在的问题是自己主机上查看或者云监控上看着,这些容器内存占用都比较稳定,统计的结果加起来都不会超过500M(关注一下这里)
但是运行几天后整个主机的内存一直在慢慢消耗,没有释放
一旦我去重启这些worker进程的容器或者说直接采用reload的方式去控制重启进程,都会释放出大量的内存(2G+)
400M->2G
这些内存究竟是从哪来的?