偶然看到这样一篇文章:《使用 pprof 排查 Golang 内存泄露》https://www.toutiao.com/i6881796351139676680/

最后一段让我很疑惑:

修改 for ... select ... time.After 造成的内存泄露
原来程序中存在如下代码: for {
select {
case a := <-chanA:
... case b := <-chanB:
.... case <-time.After(20*time.Minutes):
return nil, errors.New("download timeout")
}
time.After 就是封装了一层的 NewTimer, time.After 的源码: func After(d Duration) <-chan Time {
return NewTimer(d).C
}
修复该错误, 只调用一次 NewTimer: downloadTimeout := time.NewTimer(20 * time.Minute)
defer downloadTimeout.Stop()
for {
select {
case a := <-chanA:
... case b := <-chanB:
.... case <-downloadTimeout.C:
return nil, errors.New("download timeout")
}

连官网的例子都是:case <-time.After(xxx), 为什么这里就出现内存泄露了?

感谢yifhao同学耐心细致的讲解:

  • 20 * time.Minute 这个时间太长了
  • 如果1s钟调用这里1000次, 那就可能会同时存在20601000个定时事件
  • 退出select的作用域的时候,time.After(20*time.Minutes)产生的对象不会被GC,走到runtime里的timer调度去了
  • 退出作用域不会被释放. 定时事件作用域在timer的调度器上去了。定时器是全局对象. 调度到了才被释放。
  • 因此,时间短,且循环不频繁的情况下,case <-time.After(xxx)这个写法还是可以的

【涨姿势】原来golang的case <-time.After(xxx)还有这样的坑的更多相关文章

  1. python os.popen('xxx.py') 遇到的坑 (No Child Processes)

    1.调用系统库 platform.system() 报错: 2.os.popen() 打开的文件流未关闭也会出现这种错误. f = os.popen() f.read() f.close() 问题复现 ...

  2. Golang核心编程

    源码地址: https://github.com/mikeygithub/GoCode 第1章 1Golang 的学习方向 Go 语言,我们可以简单的写成 Golang 1.2Golang 的应用领域 ...

  3. golang 解码未知键的 json 字符串

    我们可以使用 interface 接收 json.Unmarshal 的结果,然后利用 type assertion 特性来进行后续操作. package main import ( "en ...

  4. golang深坑记录

    go深坑:1.gin.context.JSON,如果没有make数组时,数组返回为null,make后,数组为[]2.json.Number转int64类型 datatemp.(json.Number ...

  5. Golang switch语句总结

    switch 语句基本结构 switch 条件表达式 { case 常量表达式1: 语句 1 case 常量表达式2: 语句 2 . . . case 常量表达式n: 语句 n default: 语句 ...

  6. golang Linux下编译环境搭建

    1.下载golang1.4和1.10源码(1.4以后的版本都用1.4go编译安装,所以先安装1.4) 2.解压后我的目录结构是: /opt/xxx/golang |-------gopath     ...

  7. 初生牛犊不怕虎 golang入坑系列

    读前必读,下面所有内容都是来自这里. 放到这里的目的,就是为了比对一下,哪里的读者多.平心而论,同样的Markdown,博客园排版真心X看,怎么瞅怎么X看.(X := '难' || X :='耐' | ...

  8. PBFT概念与Go语言入门(Tendermint基础)

    Tendermint作为当前最知名且实用的PBFT框架,网上资料并不很多,而实现Tendermint和以太坊的Go语言,由于相对小众,也存在资料匮乏和模糊错漏的问题.本文简单介绍PBFT概念和Go语言 ...

  9. go语言程序设计学习笔记-1

    https://www.jb51.net/article/126998.htm go标准库文档https://studygolang.com/pkgdoc 1. 如果想要再本地直接查看go官方文档,可 ...

随机推荐

  1. shell 文件读取批量处理

    cat ./redis-keys.txt | while read myline do echo ${myline} /usr/local/bin/redis-cli -h 000.00.00.000 ...

  2. netty系列之:小白福利!手把手教你做一个简单的代理服务器

    目录 简介 代理和反向代理 netty实现代理的原理 实战 总结 简介 爱因斯坦说过:所有的伟大,都产生于简单的细节中.netty为我们提供了如此强大的eventloop.channel通过对这些简单 ...

  3. 用setTimeout实现setInterval

    timerFun(); function timerFun() { console.log("实现操作部分") let timer = setTimeout(function () ...

  4. JAVA根据A星算法规划起点到终点二维坐标的最短路径

    工具类 AStarUtil.java import java.util.*; import java.util.stream.Collectors; /** * A星算法工具类 */ public c ...

  5. C++代码优化之nim_duilib控件关联

    前言 使用nim_duilib关联控件,优化后.的确减少了代码量,那么,执行效率呢? 时间执行的长短与硬件.软件有关,以下内容仅为参考. 测试代码 下面的代码,分为两部分, 循环使用for,非循环则直 ...

  6. java源码——计算立体图形的表面积和体积

    计算球,圆柱,圆锥的表面积和体积. 利用接口实现. 上代码. Contants.java 常量存储类 package com.fuxuemingzhu.solidgraphics.contants; ...

  7. Following Orders(poj1270)

    Following Orders Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4436   Accepted: 1791 ...

  8. Chapter 4 Effect Modification

    目录 4.1 Definition of effect modification 4.2 Stratification to identify effect modification 4.3 Why ...

  9. 微信小程序-自定义菜单导航(实现楼梯效果)

    设计初衷 在开发页面时,往往需要实现,点击页面的导航菜单页面滚动到相应位置,滚动页面实现菜单选项的高亮.在html开发中,我们可以用到a标签锚点实现,jq的动画相结合实现类似效果.在框架中vant U ...

  10. 基于Spring MVC + Spring + MyBatis的【学生管理管理系统】

    资源下载:https://download.csdn.net/download/weixin_44893902/45602690 练习点设计:模糊查询.删除.新增 一.语言和环境 实现语言:JAVA语 ...