Question1
time.After 内存泄漏代码
1 | package main |
原因分析
在for循环每次select的时候,都会实例化一个一个新的定时器。该定时器在3分钟后,才会被激活,但是激活后已经跟select无引用关系,被gc给清理掉。
换句话说,被遗弃的time.After定时任务还是在时间堆里面,定时任务未到期之前,是不会被gc清理的。
原理验证
1 | package main |
验证结果如下图所示:
从图中可以看出,实例中循环跑完后,创建了3000172个对象,由于每个time定时器设置的为3分钟,在3分钟后,可以看到对象都被GC回收,只剩174个对象,从而验证了,time.After定时器在定时任务到达之前,会一直存在于时间堆中,不会释放资源,直到定时任务时间到达后才会释放资源。
问题解决
综上,在go代码中,在for循环里不要使用select + time.After的组合,可以使用time.NewTimer替代
1 | package main |
Question2
作用域和短声明
1 | func main() { |
原因分析
不同作用域下同名变量使用短声明赋值时会产生新的变量进行覆盖
同一作用域下同名变量使用短声明赋值时不会产生新的变量,而是对同一个变量进行赋值
问题解决
1 | func main() { |