七叶笔记 » golang编程 » Golang 认识gc

Golang 认识gc

背景: 程序对内存小心的进行管理操作,控制内存的申请及释放。稍有不慎,就可能产生 内存泄露 问题,这种问题不易发现并且难以定位,一直成为困扰开发者的噩梦。

golang的GC采用的是 标记-清理(Mark-and-Sweep) 算法就是先标记出需要回收的内存对象快,然后在清理掉;

触发GC机制

1.在申请内存的时候,检查当前当前已分配的内存是否大于上次GC后的内存的2倍,若是则触发;

2.监控线程发现上次GC的时间已经超过两分钟了,触发;

每当触发的时候,在主GC线程中就会走如下的GC流程:

1.stop the world,等待所有的M休眠;此时所有的业务逻辑代码都停止

2.标记:分配gc标记任务,唤醒 gcproc个 M(就是第一步休眠的那些),分别做这个,直到所有的M都做完,才结束;并且所有M再次进入休眠

3.清理:有一个单独的goroutine去清理已经标记的内存对象快

4.start the world,设置gcwaiting=0,唤醒所有的M(不会超过P个数)

开发过程中,一定要合理的使用内存,对循环,重复变量等使用要做到心中有数,并且多使用sync.Pool, bytes .Buffer 等来控制内存的频繁gc。性能优化往往比写功能程序更有挑战,学习就是在性能调优的过程中成长最快。

小结: 因为golang中GC过程中需要把程序中所有goroutine全部停止,造成程序就像夯住一样,所以对于实时性要求比较高的程序要慎重使用golang语言。一个可以参考的建议,如果想要减少gc时间,就要减少对象数量,所以,如果可以尽量在代码中将对象进行复用。以减少临时对象数量,从而减少GC时间。

相关文章