原文地址:Go面试看这里了~(七)
1、goroutine的定义?
goroutine是与其它goroutines并行运行在同一地址空间的Go函数或方法,运行程序由一个或多个goroutine组成,与线程、进程、协程等不同,在同一用户地址空间并行独立执行functions,channels用于goroutines间的通信和同步访问控制。
2、GMP是什么?
G(goroutine):也就是协程,是用户级的轻量级线程,每个goroutine对象中的sched保存着其上下文信息。
M(machine):对内核级线程的封装,数量和CPU数一致(真正干活的对象)。
P(processor):是G和M的调度对象,用来调度G和M之间的关联关系,其数量可通过GOMAXPROCS()来设置,默认是内核数。
3、1.0前的GM调度模型?
调度器将G都分配到M,不同的G在不同的M并发运行时,都需向系统申请资源,如堆、栈、内存等,因为资源是全局的,所以会因为资源竞争而产生性能损耗,为解决这一问题,Go1.1引入P,也就是在运行时,加一个P对象,让P去管理G,M要想运行G,就需先绑定P,才能运行P管理的G。
大体可按如下几点理解:
-
全局互斥锁(sched.Lock)和集中存储状态。
扫描二维码关注公众号,回复: 13241160 查看本文章 -
goroutine传递问题(M与M之间传递可运行的goroutine)。
-
M做内存缓存,致使内存占用过高,数据局部性较差。
-
频繁syscall调用,致使严重的线程阻塞,加剧性能损耗。
4、GMP调度流程?
总结如下:
-
每个P有个局部队列,局部队列保存待执行的goroutine(流程2),当M绑定的P的局部队列满了之后,就会将goroutine放到全局队列(流程2-1)。
-
每个P绑定一个M,M是真正执行P中goroutine的实体(流程3),M从绑定的P的局部队列获取G来执行。
-
当M绑定的P局部队列为空时,M会从全局队列获取到本地队列来执行G(流程3.1),当从全局队列未获取到可执行G时,M会从其它P局部队列偷取G来执行(流程3.2),这种从其它P偷的方式成为work stealing。
-
当G因系统调用(syscall)阻塞时,会阻塞M,此时P会和M解绑,也就是handoff,并寻找新的idle的M,若无idle的M就会新建一个M(流程5.1)。
-
当G因channel或network产生I/O阻塞时,不会阻塞M,M会寻找其它runnable的G,当阻塞的G恢复后会重新进入runnable进入P队列等待执行(流程5.3)。
5、GMP调度过程中存在哪些阻塞?
-
I/O,select。
-
block on syscall。
-
channel。
-
等待锁。
-
runtime.Gosched()。
6、sysmon的作用?
sysmon也叫线程监控,用于变动的周期性检查,用处如下:
-
释放闲置超过5分钟的span物理内存。
-
如超过2分钟未垃圾回收,则强制执行。
-
将长时间未处理的netpoll添加到全局队列。
-
向长时间运行的G发起抢占调度(运行超过10ms的G,会进行retake)。
-
收回因syscall长时间阻塞的P。
7、三色标记原理?
先将所有对象放入白色集合中,之后进行如下操作:
-
从根节点遍历对象,遍历到的白色对象从白色集合中放入灰色集合。
-
遍历灰色集合对象,将灰色对象引用的白色集合的对象放入灰色集合中,同时将遍历过的灰色集合中的对象放入黑色集合。
-
循环步骤三,直到灰色对象中没有对象。
-
步骤四结束后,白色集合对象就是不可达对象,也就是垃圾,可进行回收。
至此,本次分享就结束了,后期会慢慢补充。
以上仅为个人观点,不一定准确,能帮到各位那是最好的。
好啦,到这里本文就结束了,喜欢的话就来个三连击吧。
以上均为个人认知,如有侵权,请联系删除。