首页
下载
文档
社区
视频
捐赠
源代码
赞助商
AOT 编译器
AI 助理
商业产品
PHP AOT 原生编译器
Swoole-Compiler 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
crontab + coroutine + channel内存回收不了
### 问题描述 你好,我在使用crontab + channel + coroutine组成生产者和消费者同步70W的数据,数据库是MySQL。 原本是5.4G,定时器执行之后内存开始飙升到6.8G。任务结束后这6.8G就没有变回原理的5.4G。 我的任务调度方式是:WorkerStrategy top命令发现是一个执行该定时任务的work进程占用了1.4G的内存。 ### Swoole版本,PHP版本,以及操作系统版本信息 centos7.8,php7.3,swoole4.5,hyperf版本是很早之前的。 ### 相关代码 ```php namespace App\Tasks; use Hyperf\DbConnection\Db; use Hyperf\Di\Annotation\Inject; use Swoole\Coroutine\Channel; use Hyperf\Utils\Coroutine; class InspectionTask { private const BATCH = 10000; /** * @Inject() * @var \App\Service\Supermarket\InspectionService */ private $service; public function inspect() { $count = (int) ceil($this->getCounts() / self::BATCH); $channel = new Channel($count); $this->getData($channel); $this->createCoroutines($channel, $count); } private function getCounts(): int { return Db::connection('xxx')->table('xxxx') ->count(); } private function getData(Channel $channel) { Coroutine::create(function () use ($channel) { Db::connection('xxx')->table('xxxx')->select($this->fields()) ->chunkById(self::BATCH, function ($inspections) use ($channel) { $channel->push($inspections); }, 'YWLSH', 'inspection_id'); }); } private function createCoroutines(Channel $channel, int $counts) { for ($i = 0; $i < $counts; $i++) { Coroutine::create(function () use ($channel) { $inspections = $channel->pop() ?? []; foreach ($inspections as $inspection) { $this->service->inspect(json_decode(json_encode($inspection), true)); } }); } } private function fields(): array { return [ // todo ]; } } ``` ### 你期待的结果是什么?实际看到的错误信息又是什么? 期待的结果:定时器执行后内存恢复到原来的大小。 实际上的结果:占用的内存没有释放。
发布于5年前 · 7 次浏览 · 来自
提问
MARiA
### 问题描述 你好,我在使用crontab + channel + coroutine组成生产者和消费者同步70W的数据,数据库是MySQL。 原本是5.4G,定时器执行之后内存开始飙升到6.8G。任务结束后这6.8G就没有变回原理的5.4G。 我的任务调度方式是:WorkerStrategy top命令发现是一个执行该定时任务的work进程占用了1.4G的内存。 ### Swoole版本,PHP版本,以及操作系统版本信息 centos7.8,php7.3,swoole4.5,hyperf版本是很早之前的。 ### 相关代码 ```php namespace App\Tasks; use Hyperf\DbConnection\Db; use Hyperf\Di\Annotation\Inject; use Swoole\Coroutine\Channel; use Hyperf\Utils\Coroutine; class InspectionTask { private const BATCH = 10000; /** * @Inject() * @var \App\Service\Supermarket\InspectionService */ private $service; public function inspect() { $count = (int) ceil($this->getCounts() / self::BATCH); $channel = new Channel($count); $this->getData($channel); $this->createCoroutines($channel, $count); } private function getCounts(): int { return Db::connection('xxx')->table('xxxx') ->count(); } private function getData(Channel $channel) { Coroutine::create(function () use ($channel) { Db::connection('xxx')->table('xxxx')->select($this->fields()) ->chunkById(self::BATCH, function ($inspections) use ($channel) { $channel->push($inspections); }, 'YWLSH', 'inspection_id'); }); } private function createCoroutines(Channel $channel, int $counts) { for ($i = 0; $i < $counts; $i++) { Coroutine::create(function () use ($channel) { $inspections = $channel->pop() ?? []; foreach ($inspections as $inspection) { $this->service->inspect(json_decode(json_encode($inspection), true)); } }); } } private function fields(): array { return [ // todo ]; } } ``` ### 你期待的结果是什么?实际看到的错误信息又是什么? 期待的结果:定时器执行后内存恢复到原来的大小。 实际上的结果:占用的内存没有释放。
赞
0
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
登录
后参与评论
评论
2020-12-20
鲁飞
go to https://github.com/hyperf/hyperf/issues/2964
赞
0
回复
2021-01-27
MARiA
回复
鲁飞
谢谢
赞
0
回复
2021-01-11
卡大大
是数据库读取高峰导致的,控制单次数据读取量这样内存占用就不会飚高了,mysqlnd无法释放内存导致的,非PHP脚本能释放。
赞
0
回复