持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
常见的垃圾回收:
- 引用计数
- 标记清除
- 分代收集
golng垃圾回收
-
标记清除:标记清除的本质就是标记哪些内存还在使用中-- 被引用到的,哪些内存不在使用中--不被引用的。把那些不被引用到的内存清除
- 垃圾回收开始时从root对象开始扫描,把root对象引用的的内存标记为“被引用”,考虑到内存块中存放的可能是指针,所以还需要递归的进行标记。全部标记完成之后,只保留被标记的内存,然后未标记的进行清除
-
三色标记法:黑色、灰色、白色,抽象出来的三种颜色,就代表三种状态。灰色就是被引用到的对象被扫描出来时,被放进标记队列中的状态。黑色就是会把标记队列中的对象取出来,然后把这个对象标记位黑色。再去扫描这个黑色对象所引用的对象k,最后把扫描到的对象k放进标记队列中,标记位灰色。一直递归,最后没有被扫描导的就是白色,白色就是未被引用的对象
-
STW:stop the world,在垃圾回收的过程中,回收过程需要控制内存的变化。否则指针传递会引起内存引用传递变化。比如已经用过的黑色对象,突然添加了一个白色对象,但是这个黑色对象不会重新进行扫描,那么白色对象就会被误删除。为了防止这种错误,golang就会停掉所有的goroutine,专心做垃圾回收,这就是STW。但是STW对用户体验不好
-
混合写屏障:为了减少STW的时间,Golang就对垃圾回收算法不断的进行了优化。现在使用的垃圾回收就是混合写屏障。具体的操作就是
- GC开始期间,把栈上所有扫描到的都标记成黑色
- 在栈上创建的新对象,标记成黑色
- 被添加的对象都标记城灰色
- 被删除的对象标记成灰色
这样的话,添加和删除的对象都不会被在一次GC结束被删除,不会造成误删。而会在下次GC重新扫描,标色,然后删除。但是混合写屏障只能减少STW,不能避免STW。