老大,有一个webman队列进程不释放内存的问题请教

tanhongbin

redis 队列进程消费,插件安装的,代码里面使用了静态方法, 队列跑完了数据进程内存没有释放,
跑之前:
截图
跑中:
截图
跑完后:
截图

然后我打印status 结果和跑完后一样,内存没有释放呀,需要使用单例模式 使用类的静态方法吗?
这样一直增长会不会出现内存泄露 溢出的情况呀?

1369 4 1
4个回答

walkor

消费的过程中会加载类文件到内存,消费后内存比初始内存大是正常的,随着所有类文件都加载到内存,内存就不增长了。只要不是内存无限增长就没事。

本地测试下,比如消费10万条消息,后记截图记录下内存占用,再消费10万条消息看下内存是否有明显增长。如果有的话可能是内存泄漏,需要自己定位下,找出代码中有嫌疑的地方注释掉,消费测试直到找到泄漏点。没有明显增长不用担心。一般进程占用几十M是很正常的事情。

  • tanhongbin 2022-04-27

    感谢老大,我在测试一下是不是这个问题

tanhongbin

截图
截图
截图
截图

  • walkor 2022-04-27

    getInstance方法每次都返回一个新的实例试下

  • tanhongbin 2022-04-27

    感觉我生成新的类实例,效果一样呀

tanhongbin

截图

截图

是不是上面的方法中又请求了另一个静态方法导致的?

  • 暂无评论
Chuckle

插个楼 为什么4个进程 内存差别这么大呢

  • tanhongbin 2022-04-28

    经过测试发现。内存是增长到一定量以后,消费进程重启,然后内存释放,再增长到一定量进程重启,内存释放,就这么个循环过程。

  • tanhongbin 2022-04-28

    process terminated with ERROR: E_ERROR "Uncaught RuntimeException: Workerman Redis Wait Timeout (600 seconds) in /private/var/www/api_process/vendor/workerman/redis-queue/src/Client.php:175

  • Chuckle 2022-04-28

    这个我知道 有个内存检测 如果某个进程占用内存即将超过php.ini中memory_limit设定的值,就会重启进程。但是最主要是要知道哪里在泄漏。

  • Chuckle 2022-04-28

    进程内存30多正常嘛,以及为什么请求最多的 占用内存却最小

  • Chuckle 2022-04-28

    process 意思是队列里有命令超过xx秒还没成功发送给redis服务端,触发超时。出现这个问题一般是业务有长时间阻塞的代码如sleep、curl等,或者redis读写量太大超过redis服务端承受能力。

  • walkor 2022-04-28

    30多正常。php内存管理器不一定会把空闲内存及时归还给操作系统,它会留着复用,提升性能,比如A进程刚好处理了某个业务逻辑申请了大量内存,这部分内存使用完php管理器可能不会释放,留着下次用,B进程没处理过这样占用大量内存的业务,那B进程内存占用就小一些。这也是为什么有的进程大,有的进程小,和请求量没有直接关系。30M正常,只有内存无限增长时才需要关注,占用几十M就不增长了不用管。或者你手动调用下 gc_mem_caches() 方法,它会释放部分空闲内存。

  • walkor 2022-04-28

    Workerman Redis Wait Timeout 如JhQ所说,本地缓存里的消息数据过了600秒还没有发给redis,导致触发超时。
    这种情况一般发生在短时间内产生巨量消息,redis处理速度跟不上导致的,比如redis走的外网,传输速度慢。

  • tanhongbin 2022-04-28

    老大,我这次我是真明白了,这次大家也学习不少,共同进步,奥利给

  • tanhongbin 2022-04-28

    老大,每个消费进程使用40多M 的时候就消费进程自己重启了正常嘛?如果超过50M左右就重启这个进程了

  • walkor 2022-04-28

    status 里的内存统计用的 memory_get_usage(),有些内存不会统计在内,比如emalloc() 分配的内存,php可执行文件本身占用内存。你看到40M占用实际上占用要比40M多,具体多少用ps aux查看。
    monitor监控的是整个php的占用的内存,达到最大限度的80%时回收进程。

  • tanhongbin 2022-04-28

    关键是我看了代码,真的没有用静态属性 数组 方式一直往里面放数据 , 使用静态方法,调用第三方接口就这些,内存呜呜涨

年代过于久远,无法发表回答
🔝