记杂||以java的角度来看go(GC篇)

本文类似于个人学习笔记不会面面俱到,需要读者掌握一定基本知识。

垃圾回收算法

垃圾标记算法:由于引用计数法的巨大缺陷,go和java都是直接或间接使用可达性分析算法。

垃圾回收算法:java以G1为例子,以分代GC为基础,通过分区机制、混合回收策略和智能内存管理优化。每一块(Eden、Survivor、Old或Humongous)都类似于标记-复制算法的From区和To区,这样既解决了传统标记复制算法空间利用率低的问题,同时还没有标记清除算法空间碎片化的缺点。同时G1可以设置最大STW时间,可见其先进和智能。

反观go使用的是三色标记法,标记清除算法的改进版。如果不清楚go为什么这么做,可能认为这是一种过时,缺陷大的方式。那我来讲讲:

1.为什么不使用分代GC算法?这要先说起垃圾回收,垃圾指什么?java垃圾回收的主要回收区域是堆,回收内容是堆上的对象。java的对象大部分都是在堆上分配内存的(少数进行逃逸分析和标量替换等),这样看来,在堆上分配的对象就有哪些经常用的,和不经常用的(分代GC以大部分死去对象都为新对象为前提)。这些对象先统一分配在伊甸园区,然后经常使用的对象“年龄”够大时送到老年代,不经常用的GC之后丢掉,这样既减少了GC压力,提高了吞吐等,看着非常合理。但是go哪?go也有逃逸分析,但go的逃逸分析是在编译时进行之后再决定分配在什么位置,java的只在jit编译优化时进行,效果差别巨大,这样go可以将大部分对象留在栈上,随着方法结束栈帧弹出而清除,这下剩余的对象中临时对象的占比就非常少了,使用分代GC的优势便不复存在。

2.为什么不使用标记复制算法?这点的原因很简单,用不到。go的底层采用先进的内存分配算法TCmalloc,通过三级缓存结构来管理内存,不同大小的对象会分配到合适大小的格子,使内存碎片大大减少。

其实还有着其他一些原因,比如go的开发团队在初期并没有足够时间去开发这种太过复杂的GC算法,这里便不做展开。

golang的GC

go的GC从开始到现在也已经走过了一段比较长的路。从早期单协程,多协程到go1.5开始使用三色标记+并行回收,再到go1.8引入混合写屏障为止才算较为成熟,经过这么多次的升级核心目的便是减少STW。

这里讲一下go1.5及之后是如何进行GC的:

三色标记法:将对象分为黑白灰三种颜色,从根节点开始,根遍历到的节点变为灰色,然后在从灰色节点开始遍历到的节点再变灰,同时把开始的灰节点变为黑色,这样遍历不到的节点为白色既需要进行清理的“垃圾”。简单来说黑色节点为其可遍历节点都是灰色的节点,而灰色节点是其可遍历节点未全变灰的节点,而白色为未遍历到的节点。

如果在stw时进行上述操作不会产生问题否则会造成对象丢失,但是如何不stw哪?这就用到了1.8加入的混合写屏障。防止对象丢失有两个原则:1.强三色不变式:所有白对象不能被黑引用 2.弱三色不变式:<-可以,但是白色对象必须有一个灰色对象指向他。在并发写入或删除时可能破坏这个原则,于是go便使用了屏障技术(并且是两种所以称混合):GC期间对于栈上创建的对象均为黑色(栈上的指针修改不触发写屏障,因初始栈已标记为黑色,且栈对象生命周期短暂,通过快照机制保证正确性),堆上删除和创建的对象都为灰色。(既然决定不了该不该删,那我下次再考虑)

垃圾回收循环主要包括以下部分:1.标记准备阶段(有STW,主要任务清扫上一阶段GC遗留对象)2.并发标记阶段(无STW)3.标记终止阶段(有STW,主要任务通过调步算法计算下次要达到的堆目标)

~前人栽树

Go八股文小解 文章被收录于专栏

Lotalot你干了什么?!没有golang八股文我们如何抗衡双招,Lotalot淡笑一声:“很简单,我自己写不就是了”说完,他气息终于不再掩饰,显露而出,Go八股文小解!

全部评论

相关推荐

03-18 21:45
已编辑
门头沟学院 Java
1.自我介绍2.数据库项目介绍3.你的项目里是怎么实现的事务隔离级别4.mysql的四大隔离级别和可以解决的问题5.mysql的存储引擎6.Innodb存储引擎里数据是怎么组织的7.B+树的层数一般是几层,为什么8.串行化的死锁什么时候出现9.MVCC用来解决什么问题10.B树和B+树的区别11.为什么用B树和B+树,不用红黑树12.redis为什么比较快13.redis的sortedSet底层的数据结构14.redis的持久化机制15.redis高可用了解吗,怎么做的16.哨兵的工作流程,raft算法17.redis的大key会有什么问题18.redis集群数据怎么分区19.消息队列怎么用的20.怎么保证消息不会被重复消费21.怎么保证消息时序性22.还了解rabbitmq哪些机制23.消费者ack丢失怎么办,怎么把消费者从组中去掉24.交换机是什么,作用,消息放在哪里(我说的放在rabbitmq服务器,面试官说不对,我再去了解下)25.你说你设计了数据的版本链,你会怎么清理过时的数据版本,怎么判断数据可以删除26.你项目中的日志文件是怎么设计的,说说mysql中的binlog吗27.java的垃圾回收机制了解吗28.老年代和新生代的回收算法,分别说说为什么29.三色回收算法的流程30.反问31.算法题:在排序数组中查找元素的第一个和最后一个位置总结:面试官很有水平也很有耐心。最后算法题我大概5分钟写出来了,但输入数组不知道怎么处理,面试官就没有让我处理输入输出。我代码里r=mid-1写成了r--,面试官看代码的时候还提醒我这还是二分查找吗,可惜我最后还以为是让我解释代码,真可惜了。
查看30道真题和解析
点赞 评论 收藏
分享
评论
点赞
2
分享

创作者周榜

更多
牛客网
牛客企业服务