还没正式上班,朋友来个电话让我帮忙排查一个问题。说是用 golang 写的牛逼的调度服务出现了内存泄露问题,Go 内存在任务暴增的时候增长很诡异。

从上线部署起,只要上游任务一上量就 oom 了。大过年的只能靠 supervisord 来重启。

本来寻思回北京再说,但这货大呼 golang 不靠谱,有内存泄露问题,没有他的 c++ 和 python 靠谱。无语,看来这个忙要帮……按照我的经验来说,oom 基本是因为人为的一些边界没控制好引起的。

先是看了他的烂代码,一个 golang 代码让他写出了 python pep8 的风格。代码里很多业务的逻辑,很晕,这么盲看也看不出个什么东西。直接用 go tool pprof 分析 golang 函数内存申请情况。果然可以看到不断的创建 time.After 定时器。

搜索代码里发现只有一处在创建 time.After 定时器,跳转过去,果然是问题代码。

for 循环里的 select 有两个 case,一个是 被其他 goroutine 不断输入任务的 chan,另一个是 time.After 定时器。当 queue 有任务时,那么 time.After 不会在该 select 里唤醒。而且,for 循环每次 select 的时候,都会实例化一个个新的定时器。该定时器在 3 分钟后,才会被激活,但是激活后已经跟 select 无引用关系,被 GC 给清理掉。

换句话说,被遗弃的 time.After 定时任务还是在时间堆里面,定时任务未到期之前,是不会被 GC 清理的。

// xiaorui.ccfunc useTimeAfter(queue <-chan string) {defer wg.Done()for Running {select {case _, ok := <-queueif !ok {return}...case <-time.After(3 * time.Minute):return}}
}

我们可以在 golang 程序里打印输出 runtime.MemStats 数据。经过测试,在差不多 3 分钟后,golang 的 heapObjects 数减少了,heapObjects 减少意味着我们上面的说法是对的。

通过 prometheuslinux free -m 看到的内存依然很大,这是因为 golang 是有内存池的,GC 在标记清除后,不会立马把空闲的内存还给系统,而是等待 5 分钟后的 scvg 来释放内存。

下面的 grafna 显示内存释放的时间是 10 分钟,分析了下 GODEBUG gctrace =1 日志,激活定时器和强制 2 分钟的 GC 和第一次的 scvg 的时间碰巧错开了,导致第一次 scvg 没有释放内存。以前测试 channel、map 的内存回收时,也遇到过该问题。

既然已经知道 Go 内存暴增的问题是由于“不断的创建 time.After 对象”,那么我们可以使用 NewTimer 来做定时器,不需要每次都创建定时器对象。代码如下:

// xiaorui.ccfunc useNewTimer(in <-chan string) {defer wg.Done()idleDuration := 3 * time.MinuteidleDelay := time.NewTimer(idleDuration)defer idleDelay.Stop()for Running {idleDelay.Reset(idleDuration)select {case _, ok := <-inif !ok {return}// handle `s`case <-idleDelay.C:return}}
}

总结

有经验的 gopher 都知道,在 for 循环里不要使用 select + time.After 的组合,有坑。当遇到性能和内存 GC 问题时,都可以使用 golang tool pprof 来排查分析问题。

分析 Go time.After 引起内存暴增 OOM 问题相关推荐

  1. glibc(ptmalloc)内存暴增问题解决

    from:http://blog.chinaunix.net/uid-18770639-id-3385860.html 点击(此处)折叠或打开 #include <stdio.h> #in ...

  2. iOS内存暴增问题追查与使用陷阱

    iOS平台的内存使用引用计数的机制,并且引入了半自动释放机制:这种使用上的多样性,导致开发者在内存使用上非常容易出现内存泄漏和内存莫名的增长情况: 本文会介绍iOS平台的内存使用原则与使用陷阱: 深度 ...

  3. android 图库 imgcache.idx,iOS开发 - 关于列表图片渲染内存暴增问题

    关于列表图片渲染内存暴增问题 - (void)viewDidLoad { [super viewDidLoad]; [SDImageCache sharedImageCache].config.sho ...

  4. 加载大量图片内存暴增导致闪退 Terminated due to memory issue(内存暴增SDWebImage加载高清大图崩溃)

    上传图片一定要压缩,一定要压缩,一定要压缩.(目前手机拍摄的图片一张几M,上传后不压缩,如果几十张一块加载展示时内存画面有点美!如果是后台上传除了需要高清以外的图也需要压缩处理) 下载大量图片时一定要 ...

  5. BitArray虽好,但请不要滥用,又一次线上内存暴增排查

    一:背景 1. 讲故事 前天写了一篇大内存排查在园子里挺火,这是做自媒体最开心的事拉,干脆再来一篇满足大家胃口,上个月我写了一篇博客提到过使用bitmap对原来的List<CustomerID& ...

  6. iOS ☞ SDWebimage 内存暴增问题

    前言 相信很多开发都用过 SDWebimage 来解决 UITableView/UICollectionView 滑动卡顿等问题,而且很多公司在面试的时候都会被问到 SDWebimage 运行流程等问 ...

  7. 关于Services.exe开机CPU内存使用暴增解决方案

    这两天系统(Windows Server 2003 SP2)开机,发现Services.exe进程CPU使用率暴增并且伴随内存狂耗,内存和虚拟内存可以在10分钟之内耗尽.我3G内存呀,外加2G虚拟内存 ...

  8. 流量暴增,掌门教育如何基于 Spring Cloud Alibaba 构建微服务体系?

    作者 | 童子龙  掌门教育基础架构部架构师 **导读:**本文整理自作者于 2020 年云原生微服务大会上的分享<掌门教育云原生落地实践>,本文主要介绍了掌门教育云原生落地实践,主要围绕 ...

  9. Android 内存暴减的秘密?!

    作者:杨超,腾讯移动客户端开发 工程师 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. 原文链接:http://wetest.qq.com/lab/view/362.html WeTe ...

最新文章

  1. Android源代码获得方法
  2. Android获取手机短信
  3. pandas清华镜像_一款可以像操作Excel一样玩Pandas的可视化神器来了!
  4. 关于eclipse的indigo版中文注释时字体太小的问题(转)
  5. 暑期训练日志----2018.8.5
  6. sphinx xmlpipe2 php,PHP+MongoDB+Coreseek/Sphinx打造搜索引擎
  7. SSH项目搭建-01-使用idea创建Maven工程
  8. C2P工业云进销存管理有什么优势?
  9. 神经内分泌肿瘤如何分级,神经系统分级调节概念
  10. 拜登签署芯片法案后,英特尔股票的前景如何?
  11. Raki的读paper小记:OFA: UNIFYING ARCHITECTURES, TASKS, AND MODALITIES THROUGH A SIMPLE Seq2Seq FRAMEWORK
  12. Java多线程:synchronized | Volatile 和Lock和ReadWriteLock多方位剖析(一)
  13. 男友是程序员,看着他压力大我难受。有哪些缓解压力的好方法?
  14. 内卷的国货彩妆下,完美日记还能“火”多久?
  15. 基于vue3+ts+scss的后台管理系统(二)----excel的导入导出
  16. 计网PPT 第八章 互联网上的音频和视频服务
  17. 集线器,路由器,交换机的作用和差别是什么?怎样区分交换机,集线器,路由器?...
  18. Quartus II 操作入门
  19. python设计拼图小游戏_关于python:教你用Python自制拼图小游戏轻松搞定熊孩子
  20. 人在死去的一瞬间是否会害怕,这些回答够真实,也让人落泪

热门文章

  1. IAR不进调试界面DEBUG界面,直接烧写程序。完美解决,还可以添加到工具栏
  2. intelij idea启动之谜
  3. [DeeplearningAI笔记]卷积神经网络2.9-2.10迁移学习与数据增强
  4. ADF_Tutorials系列17_ADF Faces_使用布局组件
  5. 史上最全PHP正则表达式实例汇总
  6. Windows2003 SQL2005解决系统Administrator密码不知道的问题
  7. 【转载】2010年最全最新令人无语语录
  8. CodeForces - 1579G Minimal Coverage(dp)
  9. 牛客 - 做计数(数学)
  10. HDU - 2594 Simpsons’ Hidden Talents(KMP的next数组)