我的应用是要顺序跑每一天的数据,每天的数据都很大,每天的数据单独处理,没有全局变量,循环执行。
一开始我还像这样写过:
var bigData
map[string]map[string]float64
func generateData()
{
}
func useData() {
}
后来出现内存问题后,深感这样写法的问题之大,遂改为:
func generateData()
map[string]map[string]float64
func useData(bigData
map[string][map[string]float64)
数据由谁生成,由谁使用,什么时候不再有用,就清晰很多,我想对于GC也是一样吧。
这样就会遇到和解决不同种类的问题,这样才能进一步的提高自己的Craftsmanship。
结果使用top查看时发现,内存使用直线上升,每次循环使用的内存根本没有释放,结果就是:内存耗尽。
用惯了高级语言的我,好久都没遇到这么底层的问题。
我的直接疑问是:难道Go的GC没有发现那些应该回收的内存吗?
结果Google了一下验证了我的判断:在Linux 32位机上的GC机制确实有问题,我耐性的看完了整个回帖。
有人扬言不解决这个问题就不使用Go,推荐的解决方案大部分是迁移应用至64位系统,还有让等Go 1.1版。
我想怎么就这么中枪了呢?刚刚开始欣喜的使用Go就遇到这么大的问题。
不能迁移至64位系统,不能等新版本,只能自己想办法。
还好,根据回帖里面的建议,首先使用源码编译了一份最新版本的Go(go 1.0.3, 原来是1.0.2),然后在
每次循环后加上runtime.GC(),结果问题解决。
收获:
1. 低级别的语言带来执行效率的同时会带来一些基础的问题需要你面对,比如内存管理。
2. 使用Functional编程的思想来写程序,让数据干干净净来,干干净净走。比如:
bigData = make(...)
bigData....
3. 在the 8th light
blog上看过一篇文章,他就强烈建议一个好的程序员应该高级和低级的开发语言都使用过,
有疑问加站长微信联系(非本文作者)